środa, 26 kwietnia 2017

Dzień 35. i 36.

    Po przyjściu do pracy, zajrzałem do maili i dostałem jakąś poprawkę we front-endzie. Przyjrzałem się temu i trzeba było ostylować widgety w twigu. Ostylowałem jeden i działał. Wtem nagle podchodzi PM (który mi to zadanie zlecił) i spytał co robię. Powiedziałem więc, że to co dostałem od niego, a on na to, żebym to zostawił, bo przejmie kolega. Mówię, że już zacząłem i to jest góra 15 minut roboty, ale i tak miałem zostawić i zająć się czymś nowym. Zostawiłem, ale z pół godziny zeszło.

    Nowy projekt, który dostałem jest elementem projektu, przy którym już pracowałem, tyle że połączonym biznesowo a nie kodowo, bo tam był to CRM dla tej firmy, a tutaj jest CMS i coś się ponoć nie wyświetla na stronie po edycji po stronie admina. Instalacja projektu wydawała się prosta, bo już to robiłem parę razy, więc nawet nie muszę sięgać do notatek. I wszystko byłoby dobrze, gdyby życie było proste. Dojście do tego, że nie mam nowej bazy i .htaccess blokuje mi część projektu oraz że Firefox zapamiętał sobie przekierowanie i za cholerę nie chce korzystać ze zmian, zajęło mi chyba z 1,5 h, zanim udało się ten projekt uruchomić lokalnie. Wcześniej parę razy słyszałem, że "jak coś Ci nie działa to sprawdzaj na devie albo na teście", a tym razem się okazało, że tam dawno nic nie było aktualizowane i nie mam co sprawdzać...

    Projekt w końcu uruchomiłem. Pierwsza poprawka przy której zacząłem grzebać przeszła na później, a zająłem się prostszą, czyli zmianami związanymi z zamówieniami w związku ze zbliżającą się majówka. Dostałem wskazanie na kawałek kody, gdzie było to już robione, więc po prostu musiałem dopisać swoje ify i else'y. Dopisałem, zablokowałem 1 maja w kalendarzu we froncie i byłem zadowolony. Dzień później okazało się, że miałem zaćmienie mózgu i trochę w moich ifach brakowało warunków...

   Następnym zadaniem był brak aktualizacji z CMS-a. Tutaj już nie było tak wesoło. Trochę pomógł profiler z Symfony, ale bardziej pomógł kolega, który coś już przy tym robił. W profilerze znaleźliśmy błąd walidacji formularza, więc zaczęło się szukanie co jest nie tak. Kombinacje ze zmianą assertów w encjach i wyświetlaniu odpowiednich pól trochę pomagały, ale problem i tak przeciągnął się do dnia następnego. Dzień później rozgrzebałem to dalej, pousuwałem pewne pola, które i tak się nie pojawiały we froncie i ustaliłem z architektem, że to słuszna poprawka, więc wywalamy z klasy to pole na stałe. Teraz przeklikałem edycję i wszystko się walidowało i wyświetlało jak należy.

    Wysłałem merge request do seniora, ale później się okazało, że nie zauważył i czekał aż mu powiem, że skończyłem. Z drugiej strony z PM-em mam ciągle tak, że do mnie przychodzi spytać o postępy i ciągle ma coś nowego, więc pomyślałem, że pewnie nic dla mnie nie mają, to sobie coś sam porobię. Poczytałem sobie i potestowałem jak się używa serwisu Toggl.com do mierzenia czasu pracy. Później zabrałem się za poprawki w htaccessie, przez który miałem problem z tym projektem i poprawiłem jeden warunek, żeby nie przepisywał nagłówków, jeżeli jest uruchamiany na localhoście. Następnie pomyślałem, że skoro baza w projekcie jest nieaktualna i skrypt do budowania projektu nie bardzo działa jak trzeba, to pogrzebię w tym. Zrobiłem więc nowego dumpa i musiałem przepisać kawałek skryptu build.sh, bo nie wyrabiał się z rozmiarem nowego dumpa. Wyciągnąłem aktualny konfig MySQL-a z parameters.yml i dzięki temu mogłem mieć hasła, żeby wczytywać dumpy ze skryptu bez pytania o nie, przy każdym uruchomieniu skryptu. Od teraz, w razie popsucia czegoś w bazie, wystarczy odpalić skrypt budujący i wczyta nam od nowa bazę, wykona migracje i zbuduje CMS.

    Zbierając się do domu, senior zapytał czy skończyłem, więc powiedziałem, że tak i już dawno, a w tym czasie porobiłem to i tamto. Okazało się, że miał dla mnie jakieś zadanie, tylko czekał aż powiem, że już skończyłem a nie tylko zmiana opisu w GitLabie. No ale to kwestia tego, że z każdym się inaczej pracowało, a PM mi ciągle stał nad głową. Generalnie i tak to następne zadanie jest "nieprojektowe", czyli... reinstalacja jakiegoś laptopa, żebym czasem nie zapomniał jak to cudownie pracować w supporcie. ;)


wtorek, 25 kwietnia 2017

Dzień 33. i 34.

    Połączyłem oba dni w jeden wpis, bo wydaje mi się, że pojedyncze byłby za krótkie, a oba się ze sobą łączą. Tak więc, napisałem konwerter do Excela i przyszła próba na pierwsze uruchomienie. Od razu wyskoczył "zły duch Symfony" i czytam opis błędu. Obiekt nie może być użyty jako string, czyli jesteśmy w domu. Niby, bo zupełnie nie mam pojęcia czemu miałoby się to stać. No to bezczelnie ładuje tam metodę __toSring() z nadzieją, że coś mi wyświetli, ale niestety nic z tego. Szukam dalej, coś zmieniam nie tu gdzie trzeba, więc i błąd się zmienia, ale to wciąż nie to. Mija pewnie z godzina i po małej przerwie wracam do projektu i oto jest! Klasyczna, nazwijmy to literówka, bo już mi się ten błąd zdarzał i zawsze był ciężki do odnalezienia, a jeszcze tutaj była krótka nazwa. Otóż napisałem: $this->$em = $em zamiast $this->em = $em. Jeden mały dolar a taka różnica... Kłopotów to jeszcze nie koniec, bo teraz błąd zamienił się w oczekiwanie na array a otrzymanie obiektu. Znowu grzebię, szukam, sapię. Ekran mam usiany var_dumpami, wszędzie widzę te arraye. Sprawdzam metody w repozytorium i tam też niby zwracaj arraye, więc wtf? Otóż po którymś z kolei die'u i foreachu wreszcie widzę w tych var_dumpach, że owszem mam tablicę, tyle że tablicę obiektów, a metoda oczekuje tablicy tablic. Jeszcze raz zaglądam do repozytorium i widzę swoją ślepotę. Sprawdzam w podobnym pliku konwertera, tylko dla innej kategorii obiektu i tam całość napisana metodami na obiektach, a u mnie wszystkie dane wyciągane są z tablic. Sprawdzam kolejne i znowu wszystko na obiektach, a tylko w tym jednym pliku było na tablicach. Pytam więc autora, czemu ten jeden plik jest wyjatkowy, bo na nim bazowałem swój kod. Odpowiedź jest mi już znana, ale o tym zapomniałem. W tym wyjątkowym przypadku, liczba obiektów była tak duża, że dużo szybciej było wykonywać operacje na tablicach. No to teraz jesteśmy w domu - znaczy mam pół kodu do przepisania. Mógłbym niby dodać nową metodę do repozytorium, ale stwierdziłem, że chcę mieć całość zrobioną metodami obiektowymi, a nie jakieś kawałki. Ta zmiana była w miarę szybka i pewnie po pół godzinie miałem już gotowy arkusz Excela, który wyświetlał dane.
    Dzień później poprawiłem trochę formatowanie niektórych komórek, np. żeby wyciągał tylko datę bez czasu, bo to niepotrzebne oraz wyświetlanie kwot wraz z jednostką "zł".

    I teraz zaczęła się ponownie przygoda pod tytułem na tych samych plikach pracowały 3 osoby, więc masz tu juniorze i ucz się mergowania kodu i rozwiązywania konfliktów. Tym razem poszło mi już raczej lepiej niż ostatnio, a poprawki robiłem bezpośrednio w PHPStormie, w którym i tak muszę to opanować lepiej, a już local history się przydawało. Złożyłem więc całość do kupy u siebie i zacząłem testować. Wszystko wreszcie działało, więc nie musiałem głośno przeklinać i pisać żalów do PM-a, że dostaję zjeb... kod, a jako junior męczę się z tym podwójnie, bo zawsze myślę, że to ja coś zepsułem i tracę czas na szukanie błędów gdzie ich nie ma. Na koniec przypomniałem sobie jeszcze, że kolega z front-endu zgłaszał jakiś błąd w filtrach. Sprawdziłem i działały jak trzeba poza jednym przypadkiem. Wpisanie daty typu "2005-00-00" olewało taką granicę w filtrach, ale nie doszedłem czemu się tak dzieje, chociaż trochę poczytałem. Nie chciało mi się też już mocno zagłebiać pod koniec dnia, a PM powiedział, żebym na razie olał i poszedł do domu. Wystawiłem więc merge requesta i architekt miał wyjątkowo czas, bo zabrał się za niego szybko na prośbę PM-a, także jeszcze mnie do siebie zawołał i omawialiśmy mój kod. Dowiedziałem się, że używanie empty() to zło, bo powoduje mindfucki, ale nie pamiętał czemu. Ja się broniłem, że czytałem na php.net, że to fajne, bo ma w sobie dwa testy. Może kiedyś się dowiem, co z tą funkcją jest nie tak.


czwartek, 20 kwietnia 2017

Dzień 32.

  Rano spróbowałem wykorzystać nowo zmergowany widok i kontroler z front-endu z tym co napisałem, ale przyglądając sie co się tam dzieje, zwróciłem uwagę, że wywoływane są nie te ścieżki co trzeba. Poszedłem do kolegi front-endowca z pytaniem, czy ja dobrze widzę, czy coś nie tak zrobiłem. On mi pokazał, że u niego jest ok i w GitLabie również. No to wracam do siebie i kombinuję z mergem jeszcze raz. Z drugiej strony, do tej pory nie wiem jak mogło mi się coś źle zmergować z tym nowym widokiem, skoro nie miałem wcześniej tego pliku. No nic, nie miałem czasu na sprawdzanie jak do tego doszło, ważne że miałem już z czym pracować. Rozpisałem się dalej ze swoją metodą na usuwanie obiektów i ich powiązań i sprawdziłem czy działa. Raz zachowało się dość dziwnie, więc dodałem metodę persist(), ale później ją pousuwałem i też działało, więc nie mam pojęcia czemu pierwszy raz nie chciało. Może coś w cache-u  było, bo często go muszę czyścić w tym projekcie. Sprawdziłem jeszcze parę razy, czy na pewno dobrze działa mi ta funkcjonalność i wziąłem się za następną. Tym razem było to usuwanie jednego obiektu powiązanego z innymi i przypisywanie go do innego. Już to raz pisałem, więc tylko skopiowałem swój kod do poprawki. O ile wtedy mam wrażenie, że nie do końca wiedziałem co się dzieje, o tyle teraz jakoś w miarę łatwo mi to szło i poprawiłem trochę poprzedni kod. Ot chociażby dzień wcześniej nauczyłem sie poprawnie pisać phpdoca. Napisałem, potestowałem, działało.

  Następnym etapem był eksport wyświetlanych danych do arkusza Excela. Znowu sie wydawało, że można skorzystać z poprzedniej funkcjonalności, ale nie do końca. Przepisałem tylko kawałki kodu i powoli dopasowuję go do tego nad czym pracuje teraz. Jutro będę kończył i okaże się, czy w ogóle sensownie to zrobiłem, bo jak zawsze są jakieś ify do ogarnięcia. :)


Dzień 31.

  Rano, jeszcze przed pracą sprawdziłem maile i czekała mnie miła niespodzianka. Niespodzianka, bo raczej się tego nie spodziewałem (takie trochę masło maślane) i myślałem, że mój wkład w ten kurs będzie za mały według ich wymagań. No ale się udało, więc nauki ciąg dalszy:

Dear Piotr,
Congratulations!
You have been selected as a winner for a full 3-month scholarship to the Android Basics Nanodegree by Google.
Out of more than 10,000 students in the EU Scholarship - Android Development for Beginners course your work and engagement on Slack and in the forums really stood out. We’ve been impressed and we’re excited for you to continue the journey and grow even stronger as an Android app developer!

  Pewnie będzie trochę ciężej, zwłaszcza że już poprzedni etap ledwo skończyłem, bo nagle mi gdzieś znikało 10 h dziennie, no ale może dam radę. :)

  W pracy miałem skończyć poprzedni projekt i poczytać o autoryzacji w Symfony i serwisach. Poczytałem jedno i drugie, ale wciąż nie potrafiłem w tym projekcie przestawić serwisu, z którego miał korzystać kawałek kontrolera do logowania. Zrobiłem w końcu poprawkę w tym co było i obrazek captcha zaczął się wyświetlać. Poszedłem do seniora, że zrobiłem w końcu tak, bo coś nie daję rady z tym przestawieniem serwisu i usłyszałem, że to tylko jedna linijka i prosta zmiana, ale wszystkie moje jednolinijkowe zmiany spełzły na niczym. Dowiedziałem się też, że skoro mam teraz chwilę czasu, to żebym sobie postawił jakiś projekt na boku i poćwiczył serwisy. No chyba, że PM ma dla mnie jakieś nowe zadania. PM jak to usłyszał od razu miał dla mnie nowe zadania, więc na razie nici z nauki serwisów.

  Nowe zadanie polegało na dokończeniu, czegoś co zaczął pisać kolega idący na urlop. Teoretycznie skorzystanie z istniejących funkcjonalności dla nowego widoku. Problem zaczął się robić w momencie, gdy się dowiedziałem, że nowy widok robi kolega od front-endu i w zasadzie nawet nie bardzo wiem jakie dane dostanę, albo co mam zwracać z back-endu. Zacząłem sobie coś tam pisać i wklejać kawałki kodu, które mogą się przydać z założeniem, że z front dostanę tablicę z id-kami, tak jak to było w innych modułach. Kolega w końcu zrobił ten widok i miałem to sobie zmergować ze swoim branchem. To chyba drugi merge w moim życiu, więc musiałem poczytać jak to się robi. Oczywiście wyszło coś nie tak, ale pokombinowałem i jakoś mi się udało pobrać te zmiany. Coś tam jeszcze pogrzebałem i skończył się dzień.


sobota, 15 kwietnia 2017

Dzień 30.

  Rano przyszedł PM spytać o postępy. Powiedziałem, że już wiem co i jak i zaraz się biorę za zmiany oraz że na pewno nie było w tym miejscu wyświetlania obrazka z captchy, ale mogę dorobić, bo widziałem gdzieś kawałek kodu, który to wyświetla. PM na to, że nie, nie, tutaj nie było obrazka i żebym nie dorabiał. Wczoraj inaczej ta rozmowa wyglądała, ale się nie zrozumieliśmy widocznie. Znaczy ja rozumiałem o co pytam. ;)
  Dodałem obsługę dodatkowych pól z odpowiedzi z API, ale stwierdziłem, że w sumie to nie wiem jak ten format docelowy ma wyglądać, bo nikt mi nie powiedział, więc muszę kogoś spytać albo znaleźć. Przyszedł senior, coś poklikał i dodał mi jakąś metodę, którą kojarzył. Mnie się coś nie podobał sposób jak się to wyświetlało (odwrotna kolejność), więc zacząłem kombinować. Godzinę później okazało się, że bez sensu kombinowałem i wróciłem do początkowego kodu.
  I teraz zaczyna się dramat. Oficjalną część zadania zrobiłem, bo teoretycznie miał działać fragment do testowania API i wyświetlać przychodzące odpowiedzi, ale ktoś niesłusznie założył, że to zadziała też w innym miejscu, bo problemem był brak wyświetlającego się obrazka podczas logowania na głównej stronie, a nie gdzieś w tle. Zabrałem się za to. Godzinę później podszedł standardowy pomagacz i narobiliśmy z 6 die'ów w kodzie, żeby sprawdzić co się dzieje. Dotarliśmy co się dzieje i gdzie, ale PM i senior zainteresował się moim rycerzem-wybawcą, że traci czas u mnie, a miał robić co innego. Senior stwierdził, że sam przyjdzie, bo przecież mój rycerz nie zna projektu. Podszedł, coś poklikaliśmy i wydawało mi się, że rozumiem co trzeba zrobić. Parę godzin później znowu tłukłem głową w mur i mina mi zrzedła. Usłyszałem, żeby poczytam o autentykacji w Symfony, bo jest "pojebana" i może wtedy zrozumiem o co chodzi. Poczytałem o serwisach ponownie, o autentykacji, ale jakoś mi się nie poprawiło. Podszedł PM przed swoim wyjściem, pogadaliśmy i powiedział do seniora, żeby do mnie przyszedł jak znajdzie czas, bo mojej minie i głosie widać, że jest mi bardzo smutno. I było, bo znowu miałem impostor syndrome i zastanawiałem się co ja tu robię. Senior w końcu i tak nie podszedł, bo nie miał czasu, a ja sobie dalej czytałem o autentykacji, bo to było jedyne co mi powiedział, gdy do niego podszedłem - miał inną robotę, przeinstalowywał system front-endowcowi. Później zaczęli nas gonić do domu, więc się zebrałem z myślą, że mam dość w Święta pewnie nie zajrzę do niczego związanego z kodowaniem i będę się odmóżdżał przy jakichś gierkach, bo nigdzie nie wyjeżdżam na święta, bo muszę je spędzić na diecie lekkostrawnej i oczyszczaniu, bo pierwszego dnia po świętach idę na badania endoskopowe. Także wesołego Alleluja tym którzy mogą jeść w święta. ;)


czwartek, 13 kwietnia 2017

Dzień 29.

  Po powrocie pochorobowym, usłyszałem, żebym się zajął jakimś bugiem, który wyszedł w mojej poprawce sprzed jakiegoś czasu. Funkcjonalność, nad która pracowałem przez ostatni tydzień, została przekazana koledze, który wcześniej w tym projekcie grzebał. Niewiele tam już zostało, ale jak zrozumiałem z komentarza chyba to skończył. Chociaż w kuchni mi mówił, że nie skończył, ale być może chodziło o inny issue, bo PM kazał zając się tym bugiem.
  Siadam do buga. Jak to się mówi, u mnie działało, bo nie wysłałbym merge requesta z niedziałającym kodem, ale faktycznie na devie kawałek kodu nie działał, co widziałem u PM-a na kompie i sam sprawdzałem. Zmieniam więc brancha na tego z poprawką, uruchamiam projekt i 500. No tak, przecież ostatnim pullem popsułem sobie bazę, więc znowu się zaczyna jazda. Próbowałem znowu zakomentowywać te genderowe kawałki, które ostatnio bruździły, ale zaczęło się coś jeszcze sypać. Pomyślałem, że w takim razie zrobię znowu pulla to może się coś naprawi i dociągną jakieś ciekawe poprawki. Zrobiłem pulla i co? I... projekt się wysypuje już na głównej stronie. Dobra - myślę - odpalam builda, niech dropuje tę bazę i ustawia wszystko jak trzeba. Robię builda, errory. Robię migrację errory. Krzyczę w końcu, że zrobiłem pulla i cały projekt się rozsypał. Podchodzi kolega i pyta czy composer install robiłem. Mówię, że nie robiłem, bo niby po co, skoro to nie świeża instalacja i skąd niby miałem wiedzieć, że to potrzebne. No nic, odpalam composera. Jeb! Pół ekranu na czerwono. Zerknąłem tylko i mówię: - Ej, composer to mi się wcześniej nie sypał. Kolega patrzy i mówi, żeby olać, może będzie działać. No ładnie... - pomyślałem. Odpalamy znowu builda i dalej nic. Zabrał mi klawiaturę i zagląda do kodu. Skasował ze 2 linijki w widoku i ze 2 w kontrolerze JS. Sprawdzamy - działa. Aha - mówi - P. miał tę poprawkę spushować. Oddaje mi klawiaturę i mówi, że robimy hotfiksa. Wywalam po 3 linijki z widoków i jedną z kontrolera. Przeklikujemy się i na razie wszystko działa. Każe mi skomitować i zrobić merge requesta na siebie. Jak na Ciebie? - pytam - Możesz akceptować em-ery? No mogę - odpowiedział. Wysyłam więc em-era i ustawiam na niego w GitLabie. Idziemy do niego i patrzę jak się loguje na deva i ściąga moje zmiany. Dobra nasza, przynajmniej w głównej gałęzi mam działający projekt, więc mogę pogrzebać w swoim kodzie, gdzie niby jest błąd. Przeglądam co się tam działo, znajduję zapytanie do bazy, które było odpowiedzialne za "niedziałanie" i robię je z parametrami na sztywno w phpmyadminie. Działa poprawnie. Patrzę jeszcze raz w kod i przy okazji łamię to zapytanie na kilka linijek, bo się długie zrobiło. Wygląda sensownie, w kontrolerze też wszystko ok, więc jeszcze raz sprawdzam, czy aby na pewno nie działa. Pierwszy test i... działa. No nic, zaznaczam więcej użytkowników - działa. Sprawdzam drugi przypadek - działa. Sprawdzam na innej kategorii użytkownika - działa. Sprawdzam po kolei wszystkie kategorie użytkowników i warianty - działa. Czary, bug się sam naprawił. Zrobiłem podsumowanie zadania opisując kolejność działań i stwierdzając, że bug jest nie do odtworzenia i prawdopodobnie była jakaś kolizja z czyimś innym fragmentem kodu, chociaż nie mam pojęcia w jaki sposób miałoby się to wydarzyć. No nic, zmieniam status zadania i robię sobie przerwę, żeby strzelić nowy popis w kuchni...

  Ostatnio, gdy tylko w kuchni pojawia się nasz prezes, mnie się musi cos przydarzyć. Nigdy mi się takie rzeczy nie zdarzały i nie byłem człowiekiem awarią. Tutaj zaczęło się od ekspresu do kawy (przy tym akurat prezesa nie było, ale się później ze mnie nabijał). Jakiś czas później ktoś źle otworzył opakowanie z kawą i tak zostawił. Mnie przy nasypywaniu do młynka dużo się rozsypało. Poprawiłem wycięcie, ale oczywiście prezes wszedł jak sprzątałem ziarna ze stołu, więc wyszedłem na jakąś ciamajdę, co nie umie kawy przesypać. Dzisiaj numer stulecia. Biorę szklankę z logiem coca-cola, chyba z jakichś prezentów z McDonalda, bo miałem podobne i nalewam gorącej wody z baniaka. Po chwili dolewam zimnej, żeby nadawała się do picia. Nagle coś upada na kratkę pod kranikami, chlapie po nogach, a mnie w ręce zostaje pusta szklanka. No, Kumar jego mać, w życiu nie odpadło mi dno od szklanki! Spoglądam z niedowierzaniem i pokazuję co się stało. Prezes znowu jakiś komentarz, że coś ze mną nie tak, ale pytam ile razy w życiu odpadło komuś dno w szklance? Kolega, który tam jeszcze był, powiedział, że raz widział taką sytuację, więc stwierdziłem, że dziękuję za pociesznie i to nie ja mam jakieś dziwne moce. Podchodzę do dystrybutora i czuję, że mokra podłoga. Patrzę, no jak ma nie być mokra jak poleciało ze 200 ml wody. No to biorę po 2 ręczniki papierowe i wycieram. I znowu i znowu. Prezes patrzy, bo widzi te ruchy. Pokazuję podłogę i mówię, że naprawdę odpadło mi dno jak nalałem wody, a nie rozbiłem tej szklanki, ani wcześniej nie podpiłowałem.

  Po powrocie na górę biorę się za nowe zadanie. Całkiem nowy projekt (no dobra, raz w nim robiłem prostą zmianę, ale to nie wymagało zagłębiania się). Znowu się zaczyna problem, że nie działa strona startowa. Czyszczę cache. Nie działa. Robię pull&build. Nie działa. Znowu marudzę, że kolejny projekt po ściągnięciu mi nie działa. Podchodzi kolega i ręcznie wywala katalog app/cache, po czym tworzy nowy. Nagle projekt działa. No litości... Na szczęście już czytałem o podobnych przypadkach, że symfoniowe czyszczenie cache'a czasem nie działa. OK, biorę się za analizę błędu. Zły duch Symfony mówi, że nie wolno korzystać z tej metody, bo jest protected. Sprawdzam - no jest. Zmieniam na public, ale znowu zły duch. Zmieniam jeszcze w klasie abstrakcyjnej i zły duch znika. Myślę sobie, no super, ale to nie może być takie proste. Ktoś w końcu założył w jakimś celu, że ta klasa ma być protected. Patrzę na autora plików - główny architekt. No nie, na pewno nie można tego tak rozwiązać. Szukam, myślę, kombinuję. No nie da się inaczej, bez dopisania kupy nadmiarowego kodu. Idę do architekta. Opowiadam i patrzymy u niego. Przegląda i mówi, że dobra, zmiana dostępu do tej metody na public jest wskazana i może coś źle założył. Wracam do siebie, poprawiam, gotowe. Minęła godzina, a mogłem to mieć zrobione w 10 minut, no ale cóż, brak doświadczenia kosztuje. A jednocześnie wiem, że nie mogę sobie frywolnie zmieniać takich rzeczy, bo wtedy cierpi bezpieczeństwo.

  Kolejne zadanie. Nasz kontroler korzysta z zewnętrznego API, gdzie chyba coś się zmieniło. Niby w naszym testerze ma się wyświetlać obrazek captcha, ale coś ja tego nie widzę w kodzie. Klikam i klikam, czytam opis zadania i w końcu mówię do PM-a, że chyba nie bardzo wiem o co tu chodzi. Ten mi o obrazku, to ja mówię, że w kodzie nie widzę, żeby się tu wyświetlał obrazek. No to on, żebym zobaczył co przychodzi w requeście z API. No widzę, że obrazek w base64, ale ja tu nie widzę wyświetlania. Słyszy to architekt i mówi, że gadam bzdury, bo na pewno było. No dobra, pytam jeszcze raz PM-a czy na pewno tu się pojawiał obrazek. On mi pokazuje w innej części aplikacji, ale obrazka nie ma. Odpala aplikację na Androidzie i też nie ma obrazka, tylko czerwony "błąd". No widzisz, a był obrazek - mówi PM. Ta, tylko nikt go nie widział - pomyślałem. Dobra - mówię - to grzebię dalej, skoro wiem o co chodzi. Pogrzebałem i jest jakiś kod który gdzieś do tempa wrzuca ten obrazek, ale za cholerę nie ma wyświetlania w tym testerze. Skaczę sobie po kodzie i analizuję co się tam dzieje, ale wpadam w klasyczną pętlę. Podchodzi mój rycerz, który ostatnio mi pomaga i pyta co słychać. To odpowiadam, że znowu się zapętliłem i moje var_dumpy nie chcą działać, a już widziałem ich efekt. Przegląda, wchodzi w jakąś metodę, zabiera mi klawiaturę i na końcu dopisuje echo "DUPA"; Odświeżam i mam "dupę" zamiast ajaksa. A więc jasne, znowu gdzieś przegapiłem kawałek kodu, którego nie zrozumiałem. Słońce zaczęło chylić się ku zachodowi, więc postanowiłem się zbierać do domu. Jutro sobie zrobię obsługę tych błędów, bo już wiem gdzie i dodam do wyświetlania obrazka, którego tam wcześniej nie było i nikt mi nie wmówi, że białe jest czarne...


Weekend i choroba.

  Pod koniec tygodnia coś się zaczęło do mnie dobierać i coraz gorzej się czułem. Weekend więc spędziłem w łóżku. W poniedziałek próbowałem się zebrać i iść do pracy, ale nic z tego nie wyszło i skończyło się na kolejnych trzech dniach w łóżku. Gdy już zacząłem trochę więcej ogarniać, a mniej spać po kilka razy dziennie, przypomniało mi się, a raczej przypomniał mi o tym mail od Udacity, że już wkrótce kończy się kurs podstaw Androida, więc pora skończyć wymagane projekty. Warunkiem przejścia do dalszego etapu jest przynajmniej wykonanie tych projektów, ale jeszcze dodatkowo mają oceniać całkowitą aktywność na forum i na Slacku. Nie liczę zbytnio na "awans" (z poprzednio zakwalifikowanych osób w liczbie ok. 10000, teraz mają wybrać 1000), bo moja aktywność tego rodzaju była mocno ograniczona - ostatnio głównie przez pracę. Poza tym, mam lepsze zajęcie niż siedzenie całe dnie na forum czy Slacku i wykazywanie się na siłę.
  Tak czy siak, zabrałem się za kończenie kursu. Znowu było trochę mielenia w front-endzie, czyli tutaj w XML-u, ale wreszcie doszło coś z prawdziwego programowania, czyli podstawy Javy. Takie absolutne, czyli co to jest zmienna, łańcuch (ktoś jeszcze tak nazywa stringi? to określenie pamiętam z zamierzchłej literatury) itp. Podali parę gotowych metod do skopiowania (głównie wyszukiwanie widoków z xml-a i operacje na nich), które obiecali wyjaśnić później (to prawda, już po skończeniu projektu była dalsza lekcja z podstaw OOP i pewnie rzeczy stały się jaśniejsze). Skorzystałem więc z tego i zdobytej wcześniej wiedzy, i zabrałem się za pisanie swojej pierwszej interaktywnej aplikacji na Androida. Do zrobienia był licznik sportowy, więc daleko nie szukając, zrobiłem jakiś mało skomplikowany do piłki nożnej, aby spełniał wymagania, czyli ze 3 przyciski i 3 różne liczniki. Efekt może nie jest imponujący, ale przynajmniej tym razem było coś z programowania, a nie tylko front-end i zawsze to jakaś satysfakcja z pierwszej "prawdziwej aplikacji". Prezentuje się ona następująco:


  Gdyby nie to, że front-end mnie tak bardzo nie kręci, to pewnie bym narysował normalne boisko, albo znalazł gotowy obrazek, ale nie czułem się najlepiej i nie miałem nadmiaru czasu. Całość złożyłem do kupy w jakąś godzinę, więc chyba szybciej niż tę pierwszą, gdzie był tylko obrazek i manipulacja tekstem i jego pozycją.


piątek, 7 kwietnia 2017

Dzień 28.

  Dzisiaj chciałem jak najszybciej zajrzeć do komputera, żeby sprawdzić ile czasu generowały się moje pliki, których generowanie zostawiłem na noc. Przychodzę, a moje biurko stoi w innym miejscu. Miejsce całkiem fajne i mam z przodu miejsce na nogi, gdzie stoi popsute krzesełko, na którym kładę stopy, także tutaj nie mogę narzekać (wczoraj przestawiałem biurko w inne miejsce, bo cały czas kombinujemy jak ustawić biurka, żeby zmieścić jeszcze jedną osobę). Siadam więc w nowym miejscu, ruszam myszką, żeby monitory wyszły ze stanu wygaszenia a tu nic się nie dzieje. Zerkam w dól, a komputer wyłączony. Powiedziałem tylko na głos, że dziękuję za wyłączenie kompa, ale zostawiłem go specjalnie włączonego, bo coś mi się generowało. No nic, na dokładne dane nie miałem co liczyć, ale zacząłem szperać po logach, bo trochę się tam zapisywało. Czas wykonania nie wyglądał zadowalająco. Wręcz mocno niezadowalająco. Widać metoda usort niespecjalnie daje radę na tak dużych zbiorach. Pogadałem o tym w kuchni z kolegą i zaczęliśmy się zastanawiać nad innymi opcjami. Pogrzebałem trochę i znalazłem metodę array_unshift(), która wstawia element na początek tablicy. Wykorzystałem ją więc w prostym ifie, gdzie przy pomocy tej metody wstawiałem mieszkańców Warszawy na początek tablicy, a metodą array_push() pozostałych na koniec. Tę drugą później zamieniłem na $tablica[] = $element, bo przeczytałem gdzieś na php.net, że tak będzie szybciej. Dokładny cytat wygląda tak:
NoteIf you use array_push() to add one element to the array it's better to use $array[] = because in that way there is no overhead of calling a function.
  Teraz testy wyszły wyśmienicie, bo przesortowanie 26000+ obiektów zajęło około minuty, a nie dwóch godzin jak przy usort(). Dalej już bawiłem się z dalszą częścią tej funkcjonalności, a więc obsługą i nazwami plików oraz aktualizacją datą ukończenia generowania całości w bazie. Tutaj znowu się zaczął jakiś problem i metoda, która dopisałem w repozytorium tej klasy nie chciało działać. Errory, które się pojawiały były dla mnie nieczytelne, więc zawołałem kolegę. On też nie bardzo od razu wiedział czemu to nie działa i trochę się bawił metodą prób i błędów. Koniec końców, okazało się, że trzeba było ustawić format daty zapisywanej do bazy, bo jakoś domyślny nie chciał działać, chociaż zupełnie nic na to nie wskazywało i obaj patrzyliśmy po sobie, że ten błąd był mega głupi.
  W dalszej części dnia zająłem się powiązanymi poprawkami we front-endzie, czyli wyświetlanie statusu generowanych plików. Napisałem jakiś podstawowy end-point, ale przerwałem w pewnym momencie, bo wciąż nie mamy rozwiązanego problemu, gdzie te pliki będą docelowo lądować i jak będą udostępnianie klientowi. Zwłaszcza, że kolega poprawia kod innej części generowania tych wysyłek i w zasadzie jeśli to się zmieni, to mój status generowania tych plików, który robiłem w zeszłym tygodniu poleci do kosza, bo sporo się może zmienić. No ale to już będziemy ustalać w poniedziałek.

czwartek, 6 kwietnia 2017

Dzień 27.

  Od wejścia do pracy, PM chciał ze mną pogadać. Czytaj zapytać jak postępują prace. Chciałem pokazać jak postępują a tu jeb, Internal Server Error 500 na głównej. Mówię, że to bardzo ciekawe, bo jeszcze wczoraj wszystko działało, więc klikam na podstronę z listą ludzi. Wyświetla się, ale już naciśnięcie mojego nowego przycisku do generowania pdf-a z etykietami adresowymi się wywala. No nic myślę, pokażę co się wygeneruje z CLI. Odpadam komendę i bum! Znowu coś. I wtedy sobie przypomniałem, że wczoraj przed wyjściem kolega poprosił, żebym przeskoczył do brancha develop i zrobił pulla a później odpalił builda. Zrobiłem, działało i poszliśmy do domu. Dzisiaj sobie zdałem sprawę, że ten build wywalił w kosmos moją bazę, ale za to w prezencie mam aktualniejsze dane... No super, ale ja w swojej bazie miałem już znane osoby ze znanymi mi ustawieniami do testowania. No nic - myślę - trzeba zrobić mig, mig jak Struś Pędziwiatr (czytaj ./app/console doc:mig:mig -n). Migracja się udała, uruchamiam skrypt do generowania pdfów i jeb ponownie. Tym razem brakuje atrybutu "gender" w encji. PM-owi mówię, że zabiję kolegę, który mnie wczoraj namówił na tego pulla, ale że mogę mu chociaż pokazać resztki z wczoraj. Pokazałem jak mniej więcej wygląda jedna strona tego pdf-a z naklejkami adresowymi. Pokiwał głową i powiedział, żebym sobie teraz spokojnie naprawiał system. Coś mi w głowie świtało, że koleżanka juniorka z biurka obok rozmawiała z kimś o kwestiach genderowych, więc spytałem czy czasem ktoś nie usunął gendera z bazy. No i okazało się, że usunął, więc ponownie pożałowałem wczorajszego pulla. Nie chciałem się bawić w cofanie migracji albo kopiowanie kodu z głównego brancha, więc szybko zakomentowałem atrybut gender w encji i aplikacja ruszyła. Do czasu... gdy nie wszedłem w edycję osoby i znowu sie wysypała, więc ponownie musiałem stoczyć gender-war. Jakoś się udało, więc puściłem generowanie pdf-a dla 500+ obiektów i zawołałem PM-a. Założeniem było 3 na 8 naklejek na jednej kartce papieru, więc zaczęły się problemy z paginacją i przesuwaniem się naklejek na kolejnych stronach. Wpadliśmy na pomysł, żeby znaleźć rozdzielczość w pikselach w 72 dpi dla kartki formatu A4. Podzieliłem to na 8 i wyszedł ułamek 105,25. Podejrzewałem, że ustawienie w css-ie height na 105.25px raczej nie zadziała, bo ciężko o ćwiartkę piksela i tak też się stało. Zawołaliśmy jedynego obecnie front-endowca, żeby coś podpowiedział, ale też na początku stwierdził, że lekko nie będzie i na pewno ćwierć piksela się nam nie wyświetli. Zaproponował skorzystanie z selektora nth-child(8) i wstawienie tam pustego diva o wysokości 2 pikseli, ale do tego trzeba było moje pojedyncze divy sklejane ze sobą bokami przerabiać na rzędy i w tym czasie kolega wpadł na prostszą metodą, czyli:

{% if index.loop % 24 == 0 %}
    <div class="spacer"></div>
{% endif %}

po stronie twiga, gdzie klasa "spacer" miała wysokość ustawioną na 2px. Dodaliśmy jeszcze testowo czerwone tło i pięknie nam ten "spacer" pojawiał się dokładnie na końcu każdej kartki. Chwilę później wykorzystałem też nowo nabytą wiedzę o index.loop, żeby policzyć liczbę naklejek.

  Trochę jeszcze poklikałem, wszystko działa i super, no to pora na test na nieco większej liczbie adresatów niż 500+. Żeby mieć odpowiedni rozmach, zaznaczyłem wszystkie osoby w bazie, a więc 43000+ i kliknąłem "Wygeneruj etykiety". Wcześniej, po chwili pojawiał się modal, który zrobiłem, z informacja, że rozpoczął się proces generowania. Teraz czekam i zerkam na devtools z przeglądarki, a tam wisi sobie szary POST i wisi. Czekam, czekam, w końcu się zazielenił i pojawił sie wyczekiwany modal. Czas oczekiwania na odpowiedź na ten request wyniósł ponad 7 sekund, no ale cóż... Uruchamiam więc proces generowania etykiet w konsoli. Pojawia się status, że przystępuje do generowania ponad 26000 naklejek. Czemu o tyle mniej? Otóż nie wszyscy z tej bazy wyrażają chęć otrzymywania korespondencji, więc bez sensu dla nich robić naklejki skoro nic im nie będą wysyłać. Czekam, czekam, sruuu, coś na czerwono. Patrzę a tam timeout większy niż 60 s i do widzenia. No to szukam o co chodzi, ale okazuje się, że nie tylko ja, bo innym też się skrypty wywalają z takim timeoutem. Szukam skąd to się bierze i nie była to komenda konwertera, tylko mechanizm Symfony. Próbowałem to obejść przez plik pośredni, ale na nic się to zdało. Wreszcie zaczęliśmy grzebać razem i okazało się, że ten timeout jest na sztywno ustawiony i niby jest metoda setTimeout(), tylko szkoda, że prywatna. Kolega dorwał się więc do klawiatury i shackował system pisząc wrappera wokół oryginalnego generatora pdf-ów. Po kilku poprawkach zaczął działać, więc wygenerowałem te tysiące etykiet i otworzyłem pdf-a. 1097 stron pełnych nazwisk i adresów robi wrażenie. Pewnie jeszcze większe zrobi na drukarce, które je dostanie do wydruku. Czas oczekiwania wyniósł ponad 900 sekund przy odpaleniu komendy systemowej do konwertera, a tutaj ze skryptu trochę dłużej, ale to dopiero początek zmartwień. Teraz kolejny etap - sortowanie. Klient zażyczył sobie, aby najpierw były naklejki dla mieszkańców Warszawy. I teraz się zaczęło szukanie sposobu jak to zrobić najlepiej. Najpierw poległem na próbie stworzenia zapytania przy użyciu QueryBuildera, bo przerosła mnie liczba encji do skakania (ponownie). Kolega zaproponował metodę usort(), ale też miałem problem z napisaniem callbacka, więc zrobił to za mnie. Zadziałało na małej próbce, więc odpaliliśmy na większej. Długo to trwało, więc przerwałem skrypt po 20 minutach, bo w zasadzie nie byłem pewien na jakim etapie wisi. Dodałem więcej informacji co krok i odpaliłem ponownie. Zatrzymał się na sortowaniu. 15 minut później poszedłem do domu i zostawiłem włączony komputer. Czekam na jutrzejsze niespodzianki i kombinowanie co z tym zrobić. Zwłaszcza, że zostało mi w tym zadaniu jeszcze trochę do dopisania i chciałbym to wreszcie jutro skończyć, więc liczę, że całkowity czas generowania takiego dużego pdf-a będzie w miarę znośny...

środa, 5 kwietnia 2017

Dzień 26.

  Od rana walczyłem z dalszą częścią wczoraj rozpoczętej części zadania. Trochę mi nie szło i jak zwykle okazało się, że jaki mi ktoś podpowie jedną czy dwie rzeczy to dalej już jakoś idzie. Najpierw miałem jakieś głupawe problemy wynikające głównie z tego, że nie ćwiczyłem pisania w php i pewne rzeczy zapomniałem i aż głupio się robi, że przecież to było takie oczywiste i niezbyt zaskakujące.
  Gdy już przeszedłem ten etap pojawił się problem, którego sam bym nie rozwiązał, bo nie znam tak dobrze Symfony. Normalnie wywołanie metody render() czy renderView() nie wymagało ode mnie żadnego zachodu, ale już wywołanie tego samego z poziomu komendy w konsoli wymagało dobrania się do odpowiedniego kontenera. Potrzebowałem tego renderowania twiga, bo tam umieściłem kod, który wyświetlał listę nazw/nazwisk, adresów itp., które następnie będą konwertowane do PDF-a, żeby nadawały się do wydruku i pocięcia na naklejki. Do konwersji html->pdf wykorzystałem jakieś znalezione w sieci rozwiązanie i bibliotekę, którą już ktoś w tym projekcie używał, ale w tak zagmatwany sposób, że sam sobie musiałem znaleźć zewnętrzną dokumentację. Dla potomnych link:

KnpSnappyBundle

  Jutro będę się jeszcze bawił w dopasowywanie tego html-a, żeby się wszystko ładnie wyświetlało i układało na stronie, a następnie dalszą zabawę z generowaniem plików i ich nazw.

wtorek, 4 kwietnia 2017

Dzień 25.

  Dzisiaj grzebałem w kontrolerze, który miał obsłużyć to co dodałem we front-endzie wczoraj. Oczywiście skończyło się na poprawkach i w kontrolerze i w widokach i kontrolerze w JS, ale nazwijmy to code refactor, bo w sumie tak byłem. Kawałek kodu przekopiowałem i dostosowałem do swoich potrzeb, a dzisiaj okazało się, że nie wszystko jest potrzebne, więc zacząłem to przerabiać. Trochę się przy okazji zaciąłem w jednym miejscu, czyli sprawdzeniu czy użytkownik nie kliknął jeszcze raz przycisku przy zaznaczonych tych samych checkboksach. Pojawiły się dwie kwestie - jak przechować te wartości, żeby się do nich później odwołać oraz jak porównać dwie tablice w JavaScripcie. To drugie jakoś rozwiązałem, a znalazłem chyba ze 4 różne sposoby i co najmniej dwa działały. Niestety coś było nie tak z tym wykrywaniem czy zmieniły się zaznaczone checkboksy przy kolejnym kliknięciu na button. Wszystko wyglądało ok, ale jednak nie działało. Porzuciłem to w końcu, bo nie było tego w założeniu zadania, a nie chcę później słuchać, że robię coś ponad, co nie było wymagane i tracę na to czas, chociaż dla mnie to forma nauki i wyzwanie. Wycofałem zmiany, poczyściłem kod i wysłałem nowe commity "nadpisujące" stare.

  Kolejną częścią zadania jest napisanie komendy wywoływanej przez php app/console w Symfony2. Wcześniej tego nie robiłem, ale samo stworzenie podstaw nie było trudne. Moja komenda zaczęła pojawiać się na liście komend do wykonania dodałem parę atrybutów i ich ustawienie w metodzie init(). Dalsza część kodu uzupełniłem na razie tylko o zapisywanie w logu stanu działania, a już obróbkę główną muszę przemyśleć jutro, bo to co mogę skopiować z istniejącej komendy, przestało tu dość mocno pasować.

  Przy okazji sprawdzaliśmy kartę WiFi na USB, która u kolegi zawieszała komputer, gdy tylko połączył się z siecią. Sprawdziliśmy u mnie i to samo, system zawisł, gdy tylko wpisałem hasło do sieci. Znalazłem jakieś rozwiązanie w postaci nowego sterownika. Ściągnąłem, skompilowałem moduł do kernela, wyłączyłem poprzedni i po restarcie działało. Szkoda, tylko że jak cos zacząłem kombinować to już nie bardzo chodziło jak trzeba i pakiety gdzieś ginęły, więc wyciągnąłem te kartę i wsadziłem swoją starą, bo było czasu na dalsze zabawy.


poniedziałek, 3 kwietnia 2017

Dzień 24.

  Dzień zacząłem od kończenia poprawek we front-endzie, które nie do końca działały. Nie pojawiał mi się jakiś modal, który powinien, więc szukałem co jest nie tak w kodzie. Zajęło to godzinę z okładem, bo coraz więcej kawałków kodu zacząłem komentować. Wreszcie, po prostu skopiowałem działający kawałek kodu z innego miejsca (poprzednio go po prostu przepisywałem, bo gdy się cos pisze to lepiej wchodzi do głowy niż zwykłe copy&paste, więc jak jest czas to korzystam z takiego rozwiązania) i zaczęło działać. Jako, że na oko wszystko wyglądało tak samo, to postanowiłem dokładnie prześledzić co może być nie tak. I oczywiście klasyczny błąd, który mi się zdarzał przy pisaniu w JavaScripcie w IDE, które nie do końca sobie z nim radzi. Błędem było odwołanie się do metody length używając słowa lengHT. Ta cholera literówka już nie wystawiała moje nerwy na próbę. Inne słowa tego typu do kolekcji to: height i weight. Co ciekawe, mój ulubiony słownik angielskiego on-line akceptuje zapytanie o błędnie wpisane słowo lenght i wyświetla poprawną pisownię i znaczenia: lenGHT?


 Po skończeniu tej części i przerwie obiadowej, zabrałem się za dalszą część projektu. Stworzyłem nową encję tam gdzie trzeba i niby to szybkie zadanie, ale jednak nad niektórymi atrybutami musiałem chwilę posiedzieć i pomyśleć, bo odwoływały się do innych obiektów. Poza tym, przy migracji bazy, okazało się, że
a) Jest drop na atrybucie, który dodawałem niedawno i na pewno nie powinno go tu być. Podejrzewam, że to brak akceptacji ostatni merge requestów, więc usunąłem te zapytania.
b) Migracja próbuje dodać nowa tabelę, która owszem nazywa się prawie tak jak chciałem, ale jednak nie tak jak podałem w komentarzu. Zacząłem szukać w google co się dzieje, ale okazało się, że pomyliłem się w komentarzu i zamiast @ORM\JoinTable() napisałem @ORM\JoinColumn(), co skończyło się tak, że nazwa tabeli pośredniej utworzyła się domyślnie.

  Dalej zacząłem już dłubać w kontrolerze, żeby dodać obsługę kawałka nowej funkcjonalności. Zrobiłem sobie 10 minutową przerwę, żeby jeszcze ze 45 minut popracować, ale gdy wszedłem na górę okazało się, że mamy się pakować, bo dzwoniła żona ostatniej osoby w firmie, która ma klucz i kazała mu jechać na zakupy. Także szybki status dnia i pakowanie się, a jutro, ze świeżym umysłem dalsza walka.