niedziela, 27 stycznia 2013

Mahout - machine learning nie tylko dla orłów

Coraz więcej danych

Nie mam dzisiaj weny dlatego od razu przejdziemy do tematu. Poniżej slajd "pożyczony" z innej prezentacji. Widzimy na nim, że ilość przechowywanych danych rośnie i to rośnie bardzo a nawet niezwykle bardzo. Można zrobić na tym biznes a słowo klucz do tego biznesu to BIG DATA

Aby przetworzyć takie ilości danych potrzeba i infrastruktury i czegoś co będzie na tej infrastrukturze działać

Mahout ma wsparcie dla hadoopa toteż jest przygotowany na pracę z ogromnymi ilościami danych.

Mahout jest fajny bo na początku nie wymaga od nas znajomości skomplikowanej matematyki. To trochę tak jak metoda Collections.sort - Do codziennego użytkowania nawet nie musimy mieć świadomości jak ona jest zaimplementowana. Jednakże gdy sortowanie staje się krytycznym elementem naszej aplikacji, wtedy musimy zejść głębiej. Podobnie jest z Mahout i Machine Learning.

Jak prosto zacząć - rekomendacje

Poniżej przykładowy kod służący do rekomendacji.
 
 private List calculateGenericReccomendations() throws TasteException {
//1
        final JDBCDataModel booksReccomendationModel = new MySQLJDBCDataModel(dataSource, "UserBookPreferences", "userId", "bookId",
                "preferences", null);
        
//2        
        final UserSimilarity similarity = new EuclideanDistanceSimilarity(booksReccomendationModel);

//3
        final int howManyUsersInNeighbourhood = 2;
        final UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(howManyUsersInNeighbourhood, similarity,
                booksReccomendationModel);
//4
        final Recommender recommender = new GenericUserBasedRecommender(booksReccomendationModel, userNeighborhood, similarity);

        final int userIDForReccomendation = 5;
        final int howManyThingsToReccomendation = 3;
        final List recommendations = recommender.recommend(userIDForReccomendation, howManyThingsToReccomendation);
        return recommendations;
    }

  1. Zaczynamy od specyfikacji modelu danych. W tym przypadku model znajduje się w bazie danych. Forma jest prosta :
    id_uzytkownikaid_ksiazkiocena
  2. Określamy podobieństwo pomiędzy użytkownikami. Idea jest ponownie dosyć prosta. Najpierw preferencje musimy przepisać na dane w układzie współrzędnym a następnie obliczamy odległość pomiędzy konkretnymi punktami. Tak zachowuje się metryka Euklidesowa wybrana w tym przypadku - użycie innej implementacji to zmiana w dosłownie jednej linijce.
  3. Bardzo prosty krok. Ustalamy na jakiej zasadzie określimy czy użytkownicy są do siebie podobni. Tutaj bierzemy dwóch najbliższych.
  4. Wrzucamy do kotła i w zasadzie gotowe. Jeśli mamy odpowiednie dane w modelu to wtedy powinniśmy otrzymać listę trzech rekomendowanych pozycji dla danego użytkownika. Ponieważ widziałem już w swoim życiu upośledzone systemy rekomendacji oparte na Random.nextInt, więc sposób przedstawiony powyżej wydaje się dosyć sensowny. Inne ciekawe pola, na których może sprawdzic się mahout to klastrowanie i klasyfikacjia

Jest jeszcze moja prezentacja z JUGa ale tym razem nie mieliśmy porządnej kamerki dlatego niewiele widać( i słychać).

niedziela, 20 stycznia 2013

BYOP po raz drugi w Łodzi

Drugie spotkanie BYOP w Łodzi miało miejsce w czasie gdy z powodu mrozu samochody nie chcą otwierać drzwi a w kraju szaleje epidemia grypy. Pomimo tego na spotkaniu wszyscy wyglądali rześko co potwierdza starą góralską prawdę, że praca z metodykami zwinnymi zwiększa satysfakcje z życia i poprawia działanie układu immunologicznego.


Poruszane zagadnienia


Podział na user story mocno zależnych od siebie funkcjonalności


Problem : Jak podzielić na user story funkcjonalność, której nie jesteśmy w stanie skończyć w jednym sprincie, a która składa się z mocno zależnych od siebie części.
Na potrzeby dyskusji przyjęliśmy błahy przykład z następującymi założeniami.
  • Mamy formularz z trzema polami
  • Nie da się zrealizować całego formularz w jednym sprincie
  • Dodanie każdego pola niesie ze sobą wartość biznesową
Podejście 1 : ukrywanie zależności technicznych w user story
  • As a User chce mieć pole1 - 3 story pointy
  • As a User chce mieć pole2 - 1 story point
  • As a User chce mieć pole2 - 1 story point
W tym przypadku zakładamy, że z pierwszym polem robimy całą obsługę formularza i przy następnych polach ta część będzie gotowa. Istnieje ryzyko, że Product Owner zmieni priorytety user story i cała misterna intryga się posypie.

Podejście 2 : jasne wydzielenie technicznego user story
  • Zaimplementować obsługę formularza - 2 story pointy
  • As a User chce mieć pole1 - 1 story pointy
  • As a User chce mieć pole2 - 1 story point
  • As a User chce mieć pole2 - 1 story point
Tutaj z kolei były dyskusje czy powinniśmy tworzyć user story, które nie niesie ze sobą żadnej wartości biznesowej oraz jak zaprezentować na demie "obsługę formularza bez pól".

Podejście 3 : niezależna wycena każdego z pól
  • As a User chce mieć pole1 - 3 story pointy
  • As a User chce mieć pole2 - 3 story pointy
  • As a User chce mieć pole2 - 3 story pointy
Ten przypadek ma w zasadzie jedyną zaletę, że Product Owner może sobie zmieniać priorytety jak chce ale poza tym ma same wady i zostało przez uczestników dyskusji określone mianem totalnie złego.

Podejście 4 : bez kombinowania
  • As a User chce mieć nowy formularz z polem1 - 3 story pointy
  • As a User chce dodać pole2 do formularza - 1 story point
  • As a User chce dodać pole3 do formularza - 1 story point
Tutaj jest opisane jasno na białym, że z pierwszym user story tworzymy formularz a kolejne pola są dodawane. Jeśli Product Owner chce zmienić priorytety i mieć pole2 przed polem1 wtedy nie ma wyjścia i trzeba dokonać zmiany w backlogu co wydaje się być logiczne. Osobiście najbardziej podoba mi się właśnie to rozwiązanie.

Grywalizacja jako sposób na code review


Co to jest grywalizacja - http://pl.wikipedia.org/wiki/Grywalizacja

Problem : Ludzie nie chcą robić code review i jak wykorzystać grywalizację aby ich do tego skłonić.

Osobiście Trudno mi opisać obiektywnie ten temat gdyż moim zdaniem programiści domyślnie chcą pisać dobry kod. Jeśli tego nie robią to znaczy, że istnieje "coś jeszcze" co ich demotywuje.

Tak czy inaczej tło problemu zostało przedstawione i rozpoczęła się dyskusja jak wykorzystać przyznawanie punktów przy okazji code review. Z tego co pamiętam każda kolejna propozycja spotkała się z pomysłem jak dany system pohakować by mieć więcej punktów. Było tez trochę teoretyzowania co motywuje ludzi, ilu ewangelistów potrzeba do wkręcenia żarówki i takie tam. Pomysłodawca zagadnienia ma sprawdzić je w praktyce i przynieść wnioski na kolejny BYOP.


Scrum a odziedziczony kod


Problem : Z dalekiego uduchowionego kraju o bogatej tradycji przywędrował do nas projekt o wątpliwej jakości technicznej - jak go rozwijać/naprawiać przy pomocy metodyk zwinnych.

  1. Słowo klucz - ScumBan
  2. Uświadom interesariuszy (piękne słowo) o ogromnym długu technicznym projektu
  3. Estymuj bugi jak user story
  4. Ponieważ pole minowe jest niezbadane więc trudno "komitować" się na określoną ilość story pointów. Kontrakt - w sprincie zrobimy minimum tyle a tyle user stories a jak uda się szybciej to bierzemy kolejne z backlogu


Poprawny model obiektowy a metodyki zwinne


Problem : Jak uzyskać poprawny model obiektowy bez BDUF (big design up front) i towarzyszącego temu podejściu marnotrawstwa (waste)

Bardzo złożony i nawet kontrowersyjny problem. Niektórzy słysząc słowa analiza czy projektowanie wyciągają kołki, czosnek i wodę święconą. Z jednej strony każda sekunda poświęcona na projektowanie rozwiązania user story, które zostanie przez PO wyrzucone lub przesunięte gdzieś na dół backlogu jest stratą, której należy unikać. To jest raczej oczywiste. Ale..

  • Po pierwsze primo: w trakcie code review łatwo poprawić jakieś zjebotwory w kodzie ale jak już ktoś źle stworzy model obiektowy to trzeba czasem poprawiać wszystko
  • Po drugie primo : jeśli kod jest współwłasnością całego teamu to czy jedna osoba może według swojego mniemania tworzyć model obiektowy, który będzie uderzał w każdego członka zespołu przez następne lata?
  • Po trzecie primo : czy mając przeanalizowane tylko user story na najbliższy sprint (bądź nawet trzy sprinty) jesteśmy w stanie stworzyć model, który będzie łatwo rozwijalny w kontekście kolejnych funkcjonalności?
Generalnie trzeba znaleźć sposób aby zacząć projektować i przestać kiedy to już nie niesie ze sobą wartości.

W trakcie dyskusji nie udało się znaleźć rozwiązania. Na chwilę obecna będziemy próbować wpleść etap analizy obiektowej do przedsprintowych spotkań planningowych. Czas pokaże co z tego wyjdzie...

Podsumowanie

Tym razem spotkanie było bardziej merytoryczne - mniej filozofowania a więcej porad. Dwie kwestie pozostały otwarte i będą dyskutowane ponownie gdy praktyka da odpowiedzi na część pytań i założeń. Kolejne spotkanie jest planowane na początku marca.

niedziela, 6 stycznia 2013

RAS,Questy i percepcja - przepis na lepsze życie w nowym roku

RAS - Wróg czy przyjaciel?

Jeden film na youtube jest wart 1000 słów.
A dwa filmiki są warte 2000 słów.

Co takiego właśnie zobaczyliśmy? Były to dwa ładne przykłady zjawiska uwagi selektywnej. Jeden z mechanizmów, który bierze w tym udział, nazywa się "Reticular activating system" (google translator tłumaczy to jako "Siateczkowy system aktywacyjny"). Ów układ działa niczym przełącznik sterujący poziomem naszej senności/pobudzenia. Jeśli siedzimy na nudnym wykładzie złącza się tryb sennego odzyskiwania sprawności psychicznej ale jeśli tylko w naszym otoczeniu pojawia się coś co uważamy za istotne dla nas wtedy następuje pobudzenie i zogniskowanie percepcji na tej rzeczy. Ale skąd wspomniany RAS wie co jest dla nas ważne? I właśnie to jest trochę niebezpieczne...

Dodatnia pętla sprzężenia zwrotnego gówna

Dodatnia pętla sprzężenia zwrotnego - uważamy, że bogaci ludzie są nieuczciwi, spośród wielu faktów RAS wyłapuje te, które potwierdzają założenia naszego modelu mentalnego - co jednocześnie wzmacnia model mentalny... To jest niestety przyczyną tego, że niektórzy ludzie wraz z wiekiem wykazują coraz mniejszą elastyczność myślenia i działania. Tylko po co kilka miliardów ewolucji stworzyło coś co ma nam szkodzić? Czy to kolejny mechanizm, który sprawdza się doskonale w polowaniu na mamuta ale szkodzi w epoce drapaczy chmur? Nie do końca.

Zaprogramuj model na szczęście

Łysy jegomość na drugim filmiku nazywa się Richard Wiseman (Dobre marketingowe nazwisko ;)). Pośród wielu ciekawych eksperymentów przeprowadził on jeden niezwykle ciekawy w kontekście tego artykułu. Tematem eksperymentu była percepcja szczęścia.

Przez 10 lat zbierał on dane od 400 ochotników w przedziale wiekowym 18-44. Dane określały czy ktoś subiektywnie czuje się szczęśliwy czy też uważa się za pechowca.1

I teraz następuje ważny moment! Wiseman zebrał wszystkich uczestników eksperymentu, dał im gazetę i kazał policzyć ilość ilustracji. Pechowcy spędzili średnio dwie minuty na wykonywaniu ćwiczenia zaś szczęśliwcom zajęło to tylko parę sekund. Czy to dlatego, że mieli szczęście? NIE! To dlatego, że na drugiej stronie widniał duży napis "Stop counting: There are 43 photographs in this newspaper. ". Dlaczego pechowcy go przeoczyli?

Wyobraźmy sobie model, który zakłada, że świat to pechowe miejsce - nic tam na nas dobrego nie czeka. Mamy proste zadanie to trzeba zrobić to zadanie - "monkey see monkeyt do." Lecz jeśli zakładamy, że szczęście nam sprzyja to RAS będzie wyczulony na wszelkie szanse jakie mogą się nadarzyć. W jednej sekundzie trafia w nas masa informacji i na bazie naszego modelu pojęciowego różne mechanizmy w naszej głowie decydują co ma być uświadomione

Więc jak zaprogramować nasz RAS na wypatrywanie szczęścia w naszym nowym młodym roku?

Questy - rozbudowywanie modelu

- Panie doktorze chciałbym rzucić palenie
- no to niech pan rzuci, palenie jest nie zdrowe a papierosy są coraz droższe
- spoko to rzucam, ile się należy
- stówka

Niestety nie jest to takie proste. Tematyka powstawania mechanizmu iluzji wolnej woli wymaga osobnego artykułu ale powyższy absurdalny dialog powinien zobrazować, że zmiany psychiki to nie "proste decyzje" - od dzisiaj robię tak i tak. Pomyślmy przez analogię - jeśli chcemy budować siłę to ćwiczymy i to ćwiczymy mądrze. Jeśli przyjdziesz na siłkę i zarzucisz 300kg na klatę to możesz sobie co najwyżej zrobić krzywdę. Podobnie należy postępować z ćwiczeniem psychiki.

Ja nazwałem ćwiczenia psychologiczne questami ale każdy może sobie nazwać je jak chce. Idea jest podobna jak do siłowych - jak zarzucisz za dużo na samym początku to zamiast rozbudowywać strefę komfortu skończysz z nowymi fobiami.

Przykładowe questy
  • Standardowe ćwiczenie na rozbudowę strefy komfortu. Poszerzenie strefy komfortu ma sprawić, że mózg uwolni się od rutynowego myślenia i zacznie przeprogramowywać RAS. Następnym razem gdy pani za ladą w sklepie powie "mogę być winna grosika" :
    • "nie, nie dzisiaj" (pusty sklep) - 5kg
    • "nie, nie dzisiaj" (kolejka) - 10kg
    • "nie, i masz oddać 17 groszy, które mi wisisz" - 20kg
  • Wystąpienia publiczne. Generalnie w trakcie wystąpienia publicznego działają te same obszary mózgu, które aktywują się gdy nasze życie jest zagrożone. Ma to podstawy ewolucyjne. Ogarnięcie tej strefy buduje poczucie większej wartości społecznej dzięki czemu dla podświadomości otworzą się nowe ścieżki, uważane wcześniej za nieosiągalne (jestem za wysoki/niski, za biedny, za gruby , za szczupły).
    • mało osób, łatwy temat - 5kg
    • dużo osób łatwy temat - 30kg
    • mało osób trudny temat - 40kg
    • dużo osób trudny temat - 80kg
    • wrogo nastawiony tłum - trudny temat (np temat "dlaczego agile jest zajebisty" na corocznym zjeździe miłośników 5 letniej analizy - 150kg
  • I jedno z trudniejszych - trzeba nauczyć się bawić na trzeźwo. Alkohol to tak jak granie z kodami. Walisz wódę, przez chwilę zapominasz kim jesteś i zaczynasz się faktycznie dobrze bawić, rano jesteś znowu tą samą osobą, ze szczotkowymi wspomnieniami, rozjebanym zdrowiem i zerową wartością rozwojową (chociaż Epizodycznie coś tam się zawsze strzeli) - na końcu tego questu jest do pokonania boss - "uniezależnienie się od wyniku" - jak uda mi się osiągnąć to opiszę.
  • Wszelkie formy medytacji z afirmacjami - "jestem zajebisty" - przy zwolnionym oddechu gdy częstotliwość fal mózgowych schodzi do alfa, te cytaty idą ładnie do podświadomości.

Moje questy, które sobie zrobiłem w ostatnim półroczu to m. in. wygłoszenie prezentacji o psychologicznych podstawach programowania przed kilkudziesięcioma słuchaczami(może nawet setka była), których przynajmniej część oczekiwała uproszczenia modelu ( programista to prosty resors) aniżeli jego skomplikowania (programista to skomplikowana istota). Dodatkowo udział w konkursie na letni kaloryfer :

Zdjecie pewnie bedzie do czasu zaorania dostępne w galerii na http://foto.perfectbody.pl/ . I takie doświadczenia sprawiają, że mózg zamiast chować się jaskini zaczyna w otoczeniu dostrzegać coraz to nowe szanse. Na nowy rok warto zaczerpnąć motto rodem z rozkazu numer 227 Rosyjskiej Wielkiej Wojny Ojczyźnianej :
Żadnego kroku wstecz Towarzysze!
Jednocześnie pamiętajmy aby nie przygnieść się 300 kilową sztangą.

1) http://www.rd.com/advice/how-to-get-lucky/ - ekspryment Wisemana

niedziela, 16 grudnia 2012

Trollejdoskop

Lista trolli na które natknąłem się w tym tygodniu w necie + opis skuteczności niektórych antytroli.

Troll - zadajesz złe pytanie


Przykład codzienny :

[użytkownik 1] - "hej, doradźcie którędy najszybciej na morskie oko".
[troll] - " to dziwne, że chcesz jechać nad morskie oko, przecież nad morzem jest cieplej i mają więcej ryb"

[troll - wersja złośliwa] - "to dziwne, że chcesz jechać nad morskie oko, przecież nad morzem jest cieplej i mają więcej ryb. Nie znasz się turystyce i lepiej, żeby ktoś ci zabrał kluczyki od samochodu bo pozabijasz nas wszystkich"

Przykład IT :

[użytkownik 1] - "hej, doradźcie jakąś bibliotekę do XXX".
[troll] - "to dziwne, że chcesz używać podejścia XXX, czy na pewno wiesz co robisz? Ja bym użył YYY"

Opis : bardzo sporadycznie osoba odpowiadająca faktycznie zasugeruje lepsze rozwiązanie ale jednak częściej kieruje się ona niedostatecznymi informacjami. Pytający podaje tylko ograniczony zestaw informacji gdyż potrzebuje jednej małej odpowiedzi na proste pytanie.

Troll - polonista


Przykład codzienny :

[użytkownik 1] - "hej, skończyła mi się wódka i chcę skoczyć do sklepu, doradźcie gdzie jest najkrótsza kolejka.".
[troll] - "Do sklepu się nie skacze a chodzi. Nie wiem czy wiesz ale skakanie to wysoce nieefektywny sposób na dotarcie do sklepu"

[troll - wersja złośliwa] - "Do sklepu się nie skacze a chodzi. Nie wiem czy wiesz ale skakanie to wysoce nieefektywny sposób na dotarcie do sklepu. Ciekawe czy jak odprowadzasz swoje dzieci do szkoły to tez im każesz skakać. takich jak ty powinno się zamknąć!"

Przykład IT :

[użytkownik 1] - "my używamy metodologii XXX".
[troll] - "kolego, metodologia to nauka o metodach. Jeśli tego nie wiesz to chyba najlepiej świadczy o tym jakim 'specem' od XXX jesteś"

Opis : Wszelkie skróty myślowe, uproszczenia czy przejęzyczenia stanowią doskonały element zaczepny dla trolla.

Troll - twoje argumenty wymyślili debile


Przykład codzienny :

[użytkownik 1] - "siema, gdzie najlepiej w samochodzie naprawić XXX?".
[użytkownik 2] - "siema, w 'Mechaniku Niedzielnym' podawali, że najlepiej udać się tu i tu ".
[troll] - "Czytaj dalej tych idiotów każą ci rozebrać samochód. XXX nie może być dobre, nie próbowałem ale to napisali idioci to musi być debilne"

[troll - wersja złośliwa] - "Czytaj dalej tych idiotów każą ci rozebrać samochód. XXX nie może być dobre, nie próbowałem ale to napisali idioci to musi być debilne. Pewnie jesteś tak samo 'inteligentny' jak oni - swój ciągnie do swojego"

Przykład IT :

[użytkownik 1] - "w artykule YZ wyczytałem, że poleca on XXX - sprawdzał to ktoś".
[troll] - "YZ podobnie jak debile z jego otoczenia wypisuję tylko takie głupoty"

Opis : Tutaj troll samo tworzy punkt zaczepny. Standardowa technika - nie mam argumentów ale wiem ,że jesteś głupi. Jeśli tylko da się trzeba zignorować

Troll nuklearny


autentyk!
[użytkownik 2] - "Czasy są trudne, musimy zapomnieć o tym co dzieliło nasze zespoły i postarać się udowodnić, że możemy pracować razem dla lepszych wynikół"
[troll] - "Nie zgadzam się,że to dobre podejście - weźmy na przykład Taki Oświęcim..."

Opis : Użytkownik ma setne sekundy aby użyć neutralizatora trollollolo zanim eksplozja nuklearna dokona definitywnej anihilacji tematu


Antytrole

  • Ignorowanie - możliwe tylko wtedy gdy natura trolla jest dobrze znana na forum i żaden inny użytkownik nie da się sprowokować. Trudne do wykonania gdy troll próbuje ośmieszyć użytkownika technikami z pola erystyki.
  • Apel o nietrolowanie - dodatkowe dokarmienie i doładowanie trolla
  • Trolem w trolla - bardzo niebezpieczne - ryzyko szybkiej eskalacji trolozbrojeń
  • Wujek cięta riposta - jeśli uda się headshot troll może zostać zneutralizowany.
  • Merytoryczne strollowanie trolla - próba przywrócenia głównej wagi wątkowi merytorycznemu - technika w trakcie badań.

niedziela, 9 grudnia 2012

Primitive obsession - czyli skąd biorą się klasy Utils

To jest tak pewne jak to, że po dniu nadchodzi noc a po pijackiej nocy nadchodzi kac - prędzej czy później w większości projektów pojawiają się klasy o znajomo brzmiącej nazwie cosTamUtils. Na osobny artykuł zasługuje wytłumaczenie dlaczego klasy "Utils" psują model obiektowy i dlaczego jest to bardzo niedobry i bardzo bardzo zły antywzorzec.

Jeśli ktoś chce zbadać ten temat to niech się zastanowi lub poszuka na necie informacji o tym czy lepiej stworzyć klasę Money czy też MoneyUtils ( ewentualnie kliknie tutaj : Utils antipattern )

Dla tych którzy wierzą, ze trzeba się pozbyć utilsowego brzemiona (tak to się chyba odmienia) poniższy tekst.

Geneza

Zaczyna się niewinnie od klasy :

 
class User{
   private String phoneNumber;
}

Mija tydzień, ceny paliwa idą w górę a w międzyczasie pojawia się nowe wymaganie aby określić numer kierunkowy.

 
class User{
   private String phoneNumber;

   public Object doSomething(){
       ...
       String directional=resolveDirectional();
       ...
   }

   private String resolveDirectional(){
          doSomethingWith(phoneNumber)
   }
}

Mija kilka miesięcy nadchodzi wiosna, w drogach zaczynają pojawiać się dziury a tymczasem w naszej aplikacji pojawia się pojęcie Biura.

 
class Office{
   private String phoneNumber;

   public Object doSomething(){
       ...
       String directional=resolveDirectional();
       ...
   }

   private String resolveDirectional(){
          doSomethingWith(phoneNumber)
   }
}

I w tym momencie doświadczony programista wzdryga się od obrzydzenia - nastąpiło powtórzenie w kodzie! Trzeba by to gdzieś wynieść ale gdzie? Ani to nie pasuje dla klasy User ani do klasy Office. To może by to gdzieś zawiesić w przestrzeni aby każdy mógł sobie korzystać - taka samotna procedurka pośród obiektów.

[IRONIA]

Niestety okazuje się, że twórcy Javy byli debilami i wymyślili sobie, że każdy koncept musi być wyrażony za pomocą jakiejś klasy. Na całe szczęście jest to słówko static...

[/IRONIA]

Chwytamy się brzytwy i głośne fanfary obwieszczają narodziny klasy PhoneUtils :

 
class abstract PhoneUtils{
   public static String resolveDirectional(phoneNumber){
          doSomethingWith(phoneNumber)
   }
}

Rozwiązanie

Jeden Kod jest wart więcej niz 1000 słów...

 
class User{
   private PhoneNumber phoneNumber;

   public Object doSomething(){
       ...
       DirectionalNumber directionalToUsersPlace=phoneNumber.directional()
       ...
   }
}

W zależności od problemu Można nawet pójść dalej i stworzyć lepszą enkapsulację:

 
class User{
   private PhoneNumber phoneNumber;

   public Object doSomething(){
       ...
       City cityToContact=phoneNumber.toCity()
       ...
   }
}

Obsesja zajętości pamięci

Wczoraj na coderetreat miało miejsce ciekawe zachowanie. Pomimo, że cel ćwiczenia był jasno sprecyzowany (chyba - mam nadzieję, że te wszystkie tłumaczenia i metafory coś dały :) ) - "uczymy się pisać doskonały kod" to jednak kilka grup jasno uzasadniło swój projekt słowami - "to zajmie mniej pamięci". Jeszcze raz głośno i wyraźnie :) Do momentu kiedy ograniczenia sprzętowe staną się problemem - nie są one problemem (i nie, nie będzie ku*wa wtedy za późno aby się o to martwić)

Dodatkowe materiały

niedziela, 2 grudnia 2012

Antywzorzec Obiektowy Manager-Helper

Przy okazji przygotowań do Coderetreat mam po raz chyba już siódmy w życiu to uczucie kiedy wydaje mi się, że w końcu zrozumiałem o co chodzi w programowaniu obiektowym. A jak to ktoś tam mawiał, jeśli coś rozumiesz to powinieneś być w stanie wytłumaczyć to małemu dziecku. No To spróbujmy.

(anty)Wzorzec Manager-Helper

Nie chce mi się znowu wrzucać co, kto, gdzie i kiedy dlatego napiszę jedynie, że kiedyś miałem okazję pracować w projekcie sprowadzającym programowanie obiektowe do następujących kroków :

  1. Stworz klasę CostamManager
  2. Gdy klasa CostamManager zacznie oscylować wokół 8 tys linii zacznij przenosić część kodu do klasy CostamHelper
  3. A jeśli jesteś naprawdę bystry to dodaj jeszcze CostamControler - wiesz, żeby było tak bardziej obiektowo.

Dlaczego wzorzec Manager-Helper to zły pomysł?

Wyjaśnienie dla dzieci

Wyjaśnimy to używając wiernej kopii Feliksa co to wszyscy pisali na fejsie, że wylądował.
Jeśli tak zdekomponujemy Feliksa to możemy mu wymienić niezależnie rączki na bardziej rakietowe, i nóżki na bardziej rakietowe i może główkę na bardziej rakietową.
Tutaj drogie dzieci nie jest tak łatwo wymienić główkę bo będziemy musieli wymienić też i jedną rączkę ( a może nie chcemy!) i kawałek drugiej. I jak teraz Feliks będzie miał część rączki rakietowej a część nierakietowej to się nam posypie. Oj trzeba zmienić wszystko :(
Tak też nie jest dobrze.
I Kontroler tak naprawdę niewiele tu zmienia

Nie dla dzieci

NA koniec polecam jedną z lepszych książek o Obiektówce jakie czytałem : Object thinking

niedziela, 18 listopada 2012

Sortowanie dużych plików i geneza sydnromu "not invented here"

Wpis ten ten dzieli się na dwie części. Jeśli interesuje cię tylko techniczne mięsko to możesz drugą część ostentacyjnie olać. Ale osobiście jednak polecam ją przeczytać gdyż może to spowodować wybitnie wnikliwą zadumę u czytelnika (lub zdenerwowanie jeśli nie znajdzie tam nic ciekawego - ale to i tak lepsze od oglądania tańca z gwiazdami - dop. redakcji)

Analiza gotowca do sortowania naprawdę dużych plików


Problem : do posortowania jest w jednej chwili N relatywnie dużych plików tektowych

Czy istenieje gotowe rozwiazanie : tak : http://en.wikipedia.org/wiki/External_sorting

Czy istnieje implementacja tegoż rozwiązania w najwspanialszym języku we wszechświecie : tudzież też : http://code.google.com/p/externalsortinginjava/

Test

Maszyna


JVM
-Dosgi.requiredJavaVersion=1.5
-XX:MaxPermSize=256m
-Xms40m
-Xmx512m
Na wejściu
Plik zawierający N kwerend geograficznych (Miasto,ulica, dom itd)

Wyniki testu

Sortowanie alfabetyczne
Rozmiar pliku Czas sortowania
50k 374 ms
500k 1181 ms


Sortowanie specyficzne według pól kwerendy (na początku kraj, później maidto itd)
Rozmiar pliku Czas sortowania
50k 2815 ms
500k 24233 ms

Zrzut z visualVm

ogólna ocena


Część druga - Syndrom "tego tutaj jeszcze nie wynaleziono"

Syndrom doczekał się swojego wpisu w wikipedii : http://en.wikipedia.org/wiki/Not_invented_here. W IT objawia się ona pisaniem, pisaniem i pisaniem od nowa rzeczy, które dawno już ktoś zaimplementował. Ile osób zamiast użycia gotowej biblioteki zaimplementowałoby sortowanie plików własnoręcznie? I znowu coś co na dzień dzisiejszy wydaje się być bez sensu znajdzie uzasadnienie w warunkach do których jesteśmy tak naprawdę przystosowani...

Powrót na sawannę

Powyżej widzimy uproszczony koncepcyjny diagram gromady liniejących małp biegających po sawannie od 100tys do kilku milionów lat temu (od nich się właśnie wywodzimy). Członek gromady oznacza osobnika będącego w gromadzie a nie członka kogoś z gromady. Przeżycie każdego osobnika było w dużym stopniu zależne od grupy i pozycji jaką w niej zajmuje. Na zajmowaną pozycję i co za tym idzie - ilość dostępnych dla danej jednostki zasobów - wpływ miały : siła, koalicje oraz potencjalna wartość dostarczana gromadzie. W tym momencie interesuje nas to ostatnie.

Załóżmy, że gromada liczy 50 osób. Mamy w niej dwóch homo sapiens, którzy są podobnego wzrostu, podobnych osiągów ale jeden z nich posiadł umiejętność odróżniania grzybów trujących od jadalnych lub tez w sprytny sposób umie zwędzić miód z ula - kto będzie miał wyższą pozycję w gromadzie (zakładając, że żaden nie ma pleców u starszyzny)? Niby oczywiste, że ten który posiadł specyficzną umiejętność ALE aby tak się stało dwa warunki muszą być spełnione. Gromada z jakiegoś powodu musi potrzebować tej specyficznej umiejętności oraz gromada musi wiedzieć, że dany osobnik ma ową specyficzną umiejętność

Powrót do biura

Zakładając, że owe wzorce zostały ewolucyjnie wyryte w nas przez setki tysięcy lat zastanówmy się jak mogą się one objawiać :

  1. Gromada potrzebuje rozwiązania problemu
  2. Umiem rozwiązać dany problem
  3. Ale, ale istnieje ogólnodostępne tanie rozwiązanie tego problemu.
  4. Mam teraz dwa wyjścia - albo samemu zaimplementować rozwiązanie i zostać bohaterem (strata szansy gromady/zysk osobisty) czy też zostać kolesiem, który tylko zadzwonił po kolesia, który zna się na grzybkach (zysk gromady/strata szansy jednostki)

Można płakać, że profesjonalista w naszym zawodzie to powinien zawsze dla gromady i ten tego i w ogóle ale przypomnę a) nie jesteśmy istotami racjonalnymi, b) nie da się tak po prostu uciąć milionów lat ewolucji.Pozostaje mi jedynie dać wskazówkę dla osób w jakikolwiek sposób generujących warunki pracy - trzeba zrobić tak aby ów "osobnik" czuł się na tyle dowartościowany sukcesami grupy aby nie potrzebował szukać kompensacji w indywidualnych sukcesach. Trochę swiatła na ostatnie zdanie może rzuci dowcip :

- Szefie, ale szef ma fajne auto!
- słuchaj, pracuje dużo, zostawaj po godzinach, wykazuj inicjatywę i bierz na siebie coraz więcej obowiązków ... to za rok będę miał lepsze