wtorek, 16 maja 2017

Dzień 39., 40. i 41.

    Ponownie kila dni w jednym wpisie, bo ostatnio nie ma dla mnie zbytnio zadań, więc się douczam. Przez 2 dni uczyłem się o serwisach w Symfony2. Znalazłem jakiś krótki kurs po polsku, a później zrobiłem przykłady z dokumentacji Sf2. Wiem już co to jest service container, jak się tworzy własne i pobiera gotowe serwisy oraz że kontroler też może być serwisem, ale o tym ostatnim czytałem jakieś artykuły, że to może być zło. Senior kazał mi też poczytać o serwisach tagowanych oraz zrozumieć, ale z tym ostatnim to nie jest tak do końca pewien, póki nie trafię na zastosowanie praktyczne. Serwisy niby też zrozumiałem i zrobiłem jakieś własne, ale jak ponownie sięgnąłem do projektu, w którym miałem zmienić serwis, to dalej nie wiem jak to zrobić, bo ten kod jest zbyt zagmatwany.

    Gdzieś w trakcie tych trzech dni, zdarzyły mi się zadania programistyczne. Jedno na godzinę, które nawet nie pamiętam, ale dwa pozostałe już ciekawsze. Projekt Manager szukał dla mnie jakichś zadań i coś tam odgrzebał, albo mu po drodze zgłoszono. Zacząłem więc dzielnie szukać błędu, który widziałem naocznie u dziewczyn z zaprzyjaźnionej firmy, z którą dzielimy biuro. Siadam do błędu, grzebię, kod wygląda znajomo, bo już coś w nim robiłem na samym początku pracy, ale i tak schodzą mi 4 godzinę na analizę, co się w tym projekcie dzieje i czemu pewne pola są różnie opisane, chociaż spełniają tę samą role, a także nie mają relacji, tylko są kopiowane. Poprawiam i działa. W międzyczasie jest mowa, że wiszą jakieś moje stare merge requesty w tym projekcie, bo PM coś tam przegląda. No to i ja przejrzę czemu to jeszcze wisi. Przeglądam, przeglądam a tam znajomy kod. Okazuje się, że już raz ten problem rozwiązałem, tylko nikt go nie wypchnął, a ja w tym projekcie poruszałem się wtedy jak dziecko we mgle, więc zupełnie tego nie kojarzyłem. Ale przynajmniej dwa raz tak samo napisałem kawałek kodu, więc pewnie jest dobrze. ;) A próby zrzucania odpowiedzialności na mnie (powiedziałem PM-owi, że już raz to zrobiłem, tylko nie zostało zaakceptowane) są po prostu śmieszne, bo nie mam obowiązku pamiętania wszystkiego co robiłem, zwłaszcza w czasach, gdy nie do końca ogarniałem co się dzieje.

   Trafiła mi się też ciekawostka, w której sam jestem sobie winny i jest w sumie śmieszna. Dostałem zadanie o braku aktualizacji wyświetlanych danych po zastosowaniu filtrów. Jedna z poprawek dotyczyła front-endu, bo korzystał nie z tych danych, które przekazywała back-end, a druga była w back-endzie i moje wersja jest taka, że zostało zrobione to źle, ale kolegi, który to pisał jest taka, że nie zostało to właściwie zaimplementowane. Ot, wyświetlanie sumy wpłat dla wszystkich użytkowników zamiast dla przefiltrowanych, to niewłaściwa implementacja. Koniec końców, napisałem własną implementację, wzorując się na kawałku kodu, który zliczał liczbę wpłat. Przepisałem zapytanie DQL zmieniając co trzeba i oglądam wyniki. Pierwszy działa, więc sprawdzam w innych kategoriach. Też działa, ale że kwoty były duże, to sprawdziłem na 3 wynikach. I tu się prawie zgadzało, gdyby nie to, że po przecinku powinno być 40 gr, a u mnie było zero. Sprawdzam gdzie indziej i to samo. No to mamy problem... Sprawdzam front-end, bo tam widziałem jakieś zaokrąglanie, ale console.log z tymi liczbami wyświetla dobry wynik. Zabieram się więc do czystego SQL-a, ale tam również jest dobrze i nie spodziewałem się, żeby było inaczej. Przeglądam kod i nagle olśnienie! Jeśli zwraca się wynik zapytania rzutowany na (int) zamiast na (float), to się nie ma co dziwić, że wyświetlają się liczby całkowite. :)


wtorek, 2 maja 2017

Dzień 37. i 38.

    Znów połączyłem 2 dni w jeden wpis, bo szkoda elektronów. Dzień 37. spędziłem na reinstalacji laptopa dla naszego Office Managera i tak zeszło z 6 h. System systemem, ale później aktualizacje, jakieś pakiety biurowe i inne takie i trochę na tym schodzi, żeby doprowadzić do użytku.
    Poza tym, dostałem jedną drobną poprawkę wycenioną na ... 5 minut. Wszystko fajnie, bo to jedna zmiana warunku true na false, ale z zegarkiem (Toggl) w ręce zmierzyłem, że zajęło mi to 7,5 minuty i to też nie całości pracy. Żeby zrobić taką poprawkę trzeba: otworzyć projekt, znaleźć odpowiedni plik (dobrze, że ja pisałem tę funkcjonalność to wiedziałem gdzie szukać), dokonać zmiany, przetestować, a wcześniej dobrze by było zrobić nowego brancha (chociaż po fakcie z developa też nie będzie tak źle), skomitować zmiany, zrobić pusha, otworzyć merge requesta, poustawiać tam co trzeba i opisać, a na koniec napisać w GitLabie, że się zrobiło. Także takie magiczne 5 minut się wydłuża do 10 co najmniej. Resztę czasu spędziłem oglądając do końca filmik o PHPStormie, który oglądałem z przerwami podczas instalacji Windowsów.

   Dzień następny, czyli dla niektórych długi weekend, spędziłem w pracy wraz z pięcioma kolegami, bo reszta wzięła urlopy. Nie było dla mnie żadnych zadań, ale przed przerwą ustaliłem z PM-em, że wyślę do niego i seniora plan czego chciałbym się pouczyć. Plan przesłałem i senior dzisiaj stwierdził, że fajnie, ale żebym głównie zajął się nauką Symfony, a nie resztą drobiazgów. Zabrałem się więc dzielnie do nauki serwisów, bo już raz robiłem podejście i wydawało mi się, że to proste i wszystko rozumiem, ale jak przyszło co do czego i większego serwisu, to już się gubiłem.
    Obejrzałem jakiś tutorial, napisałem prosty serwis na jego podstawie, ale to mi nie wystarczało, więc zabrałem się za dokumentację od Symfony. Czytam, czytam i przestaję rozumieć. Dochodzę do dependency injection i zaczyna się kłopot, bo tego już też raz nie zrozumiałem. Zacząłem więc czytać o DI. Czytam, czytam, przeglądam przykłady i nagle jakiś trybik w głowie przeskakuje. No kurde, przecież ja tego cały czas używam w kodzie, ale totalnie nieświadomie, dlatego że patrzę jak inni piszą kod i kopiuję rozwiązania. Żeby się upewnić czy rozumiem, wracam do filmiku o DI, który kiedyś oglądałem, ale totalnie nic nie zrozumiałem, bo brakowało w nim jakiejkolwiek teorii, tylko był przykład na kodzie. Teraz nagle wszystko stało się jasne. Ucieszony wstałem od biurka i pochwaliłem się swoim sukcesem seniorowi. Jak zwykle komentarz był ironiczny, ale muszę przywyknąć i zacząć olewać. Wolałbym coś bardziej motywującego, ale cóż... Generalnie postanowiłem po przerwie opowiedzieć o swoich odkryciach gumowej kaczuszce*, aby sprawdzić czy na pewno rozumiem, tylko jakoś nikogo nie widziałem w tej roli, więc zajrzałem do kodu napi... przepisanego serwisu z tutoriala i opowiadać o nim wyimaginowanej kaczuszce w myślach. Wyglądała na zadowoloną, więc teraz chętnie opowiedziałbym o tym żywemu człowiekowi. Zajrzałem też do kodu, który pisałem ostatnio - eksportera do Excela, gdzie oparty był na serwisach i też jakoś lepiej go rozumiałem. Jak będzie następna wolna chwila, to wrócę do projektu, gdzie nie potrafiłem zmienić korzystania z jednego serwisu na inny i zobaczymy, czy mój aktualny stan umysłowy to ogarnie. :)

* - Metoda gumowej kaczuszki

ś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.

piątek, 31 marca 2017

Dzień 23.

  Na razie dzień zaczął się całkiem nieźle. Co prawda, musiałem ze 2 razy poprawiać rzeczy, które wydawały się zgodne z założeniami, ale zawartość bazy jednak była trochę zaśmiecona, więc musiałem dodać trochę więcej ifów w widokach twiga i metodzie __toString() w jednej encji. Zamknąłem, a w zasadzie oddałem "do odebrania" wszystkie swoje zadania i pierwszy raz zdarzyła się chwila, że czekam na nowe, więc mam czas napisać ten kawałek tekstu. Aktualizacja pewnie znacznie później, gdy rozgrzebię nowe zadania. Na razie poprawił mi się humor, bo wreszcie mam jakieś małe sukcesy w sensownym czasie. :)

  Czekając na nowy zestaw zadań, poczytałem sobie różne mądre rzeczy i poszedłem na obiad. Po powrocie jeszcze nie było ustaleń, aż nadeszła ta chwila. Wrócił PM z programistą, usiedli koło mnie zaczęli przedstawiać mi funkcjonalność, którą mam dodać do projektu. Obok siedział akurat główny architekt, więc zapytał o numer issue i sam zaczął czytać. Porozmawialiśmy z PM-em co i jak i zaczęło się robić zabawnie, bo włączył się architekt. Najpierw do programisty, który robił dla mnie opis techniczny z pretensją, że sam nie rozumie co tu niby jest napisane i że niedokładnie. Czy mogę sobie dodać encję o nazwie "Dupa" i wstawić gdziekolwiek w projekt, czy może jednak by mi łaskawie napisali dokładniej. Dalej było, że to jest za duże zadanie dla mnie i powinno być rozdzielone na mniejsze, gdzie ja powinienem dostać prostsze kawałki, a te trudniejsze powinien dostać kolega, który robił opis zadania z PM-em i wtedy było by najbardziej optymalnie. Gdzieś tam jeszcze padło cos o kodzie w stylu: "Bo tak piszecie ten kod i opisy zadań, że później Piotrek siedzi 4 h i myśli, po czym zaczyna kurwić, że nic nie rozumie z tego co napisaliście.". Chwilę później pojawił się w zadaniu komentarz od PM-a, że drugi kolega ma rozpisać dokładniej pewne rzeczy. Ja się w tym czasie zająłem tym, co nie wymagało jakoś dużo myślenia, czyli zmiany w widokach we front-endzie typu dodanie przycisku i ikonki dla niego i dopisanie kawałka obsługi. Po drodze miałem jakieś literówki i niby proste zadanie, ale dodając do tego debugowanie, zeszło mi prawie 2 h.

  Tego dnia, wystawiłem też pierwszą w życiu fakturę, gdyż założyłem własną działalność gospodarczą (wymóg Urzędu Pracy, który mi dofinansował kurs) w grudniu 2016.

Dzień 22.

  Nie bardzo miałem wczoraj czas na pisanie, więc piszę na szybko przed pracą dnia kolejnego. Wreszcie udało się rozwikłać problem, nad którym siedziałem ostatnie 3 dni. Potrzebna była konsultacja PM-a i seniora, bo pewne części tego systemu są niezrozumiałe. Po przeskoczeniu tego etapu i zrozumieniu wreszcie jak to jest napisane, udało mi się zakończyć zadania. Za godzinę miałem też zrobione następne, bo polegało głównie na copypaście, zmianie nazw zmiennych i przetestowaniu. Zająłem się więc kolejnym zadaniem. Kolejna zmiana wyświetlania adresu. Prosta sprawa, bo tylko parę ifów w widokach. Skończyłem w godzinę (po drodze oczywiście znowu wynalazłem błąd, który byłem pewien, że nie jest spowodowany moimi zmianami w kodzie, ale i tak przeszkadzał i siał wątpliwość, plus wywalał mi Apache'a, którego musiałem restartować). Zabrałem się za czwarte zadanie, które powstało w międzyczasie zmian wyświetlanego adresu i.. tutaj znowu zonk. Zatrzymałem poprzedni merge request i sprawa jest do dogadania, bo wychodzi na to, że będę robił poprawki w poprawkach, bo niektóre założenia są niedokładne.


środa, 29 marca 2017

Dzień 21.

  Nie chce mi się za wiele pisać, bo dzisiaj to się już wkurwiłem. Albo się cofam w rozwoju, albo dostałem za trudne zadanie. Wydaje się, że to proste, bo tylko tylko dodanie nowych selectorów do filtra, tylko że wszystkie pozostałe i cały system jest inaczej zaprojektowany, więc praktycznie muszę robić nową funkcjonalność. Znowu parę godzin walenia głową w mur i gadanie do gumowej kaczki nie pomogło. Skorzystałem w końcu z pomocy kolegi, który pisał dużo w tym systemie i wciąż pamięta (skorzystałem nie dlatego, że nie chciałem wcześniej, tylko nikt nie ma dla mnie czasu), ale on też odkrywał, że pewnie rzeczy mi nie zadziałają, bo były inaczej zaprojektowane, więc muszę robić pewne fragmenty prawie od zera. Po drodze jeszcze zauważyłem bug, który później uznano za feature, ale ja myślałem, że to w moim kodzie jest błąd, bo niby czemu mi nagle znika 60 obiektów, które za pierwszym razem się wyświetlają, a później po nałożeniu filtrów znikają. Przy czyszczeniu ich stanów też się więcej nie pojawiają. Okazało się, że nie wszystko w tych filtrach się resetuje do wartości, które zwrócą wszystkie obiekty, ale to odkryłem dopiero w logach Symfony, gdzie znalazłem zapytanie do bazy, przekleiłem do phpmyadmina i przeanalizowałem, gdy się ładnie pokolorowało, wraz z zaciemniającymi obraz aliasami.

wtorek, 28 marca 2017

Dzień 20.

  Wczoraj wydawało mi się, że coś nie działa w filtrach, które poprawiałem i na pytanie PM-a powiedziałem z czym jest problem i zacząłem mu pokazywać i ... nagle się okazało, że te filtry jednak działają. Na wszelki wypadek jeszcze trochę poklikałem, ale skoro działa to zostawiłem i wziąłem się za drugą część wczorajszego działania. Wydawało się, że będzie prosto, bo miałem wskazówki gdzie i co dodać, a wczoraj już to miałem obcykane. Patrzę w kod i coś mi nie bardzo pasują porady, w których encjach dodać nowe pole. Analizuję dalej i przestało mi się podobać miejsce, w którym klient zażyczył sobie dodanie checkboksa, bo był on wykorzystywany dopiero w trzecim kroku tego pseudo-formularza, więc stwierdziłem, że nadmiarowy kod, tylko po to, żeby przekazać stan tego checkboksa dwa kroki dalej. No to ustalam z PM-em, że to bez sensu i dodam ten checkbox dopiero w ostatnim kroku, czyli zatwierdzeniu formularza. Zabrałem się za dodanie checkboksa, skopiowałem sobie wczorajsze rozwiązanie i pierwsza niespodzianka. Tamto było przystosowane do FormBuildera, a tutaj formularz był na sztywno w htmlu. Gorzej, później się okazało, że jego obsługa też nie jest po stronie Symfony, tylko jest dodatkowy kontroler w JavaScripcie, który przekazuje wybrane parametry. Sam do tego niestety nie doszedłem, ale pokazał mi to kolega, który sporo pisał w tym projekcie. Dalej doszło do grzebania w back-endzie, gdzie miała powstać główna funkcjonalność, czyli masowe ustawienie true na obiektach, które biorą udział w innej operacji. W operacji, która jest oderwana od głównego wątku, bo przygotowuje tylko ustawienia, które następnie uruchamiane są z crona, bo mogą trwać bardzo długo. Od razu pomyślałem, że przemielenie tysięcy obiektów w pętli źle się skończy, wiec na wszelki wypadek spytałem seniora czy dobrze myślę, że muszę dodać nowa metodę do repozytorium. Później jeszcze coś pogrzebałem i znowu doszedłem do etapu tłuczenia głową w ścianę. Powtarzające się nazwy encji z różnymi przyrostkami zaczęły mi się dwoić i troić przed oczami i przestałem rozumieć co się dzieje. W międzyczasie senior gadał z kolegą, który to pisał i razem coś tam ustalili, a ja dowiedziałem się wreszcie gdzie powinienem dodać nowy kod, a kolega, który to pisał miał mi pokazać palcem coś innego. Efekt był taki, że wciąż się męczyłem, więc poprosiłem kolegę o pomoc. Wymieniliśmy się wiedzą, bo ja chwilę wcześniej rozwiązywałem mu jakiś problem na serwerze linuksowym. Koniec końców, kolega siadł ze mną i podpowiadał mi pewne rzeczy. Niestety przy zapytaniu przy użyciu QueryBuildera zaczęły się problemy i oddałem klawiaturę. Kolega poprzeglądał kod i zaczął przeklinać. Stanęło na tym, że zamiast QB napisał zapytanie w czystym SQL-u i tu już było trochę mniej poprawek. Gdy okazało się, że działa, resztę kodu z prostymi ifami dopisałem sam i rozszerzyłem funkcjonalność na przyszłość, bo wcześniej pytałem PM-a o trzeci przypadek działania, który nie został jeszcze ustalony/wymyślony. Zajęło mi to wszystko z 7 h, a miało być proste, jak zawsze, zwłaszcza, że rano powiedziałem PM-owi, że pewnie zajmie mi to ze 2 h, ale wtedy jeszcze nie znałem czekających mnie niespodzianek...

  Był to więc dzień z epizodem "Co ja tu robię? Trzeba było zostać ninją.", ale na szczęście jakoś się udało. Udało się też wyjść o normalnej porze z pracy, więc poszedłem na siłownię, po tygodniowej przerwie i chociaż ciężko mi się było zebrać, to się opłaciło. Ćwiczę sobie powoli martwy ciąg, czego kiedyś nie umiałem i wszyscy się bali tego ćwiczenia, bo można sobie zrobić krzywdę, ale zrobiłem spory research i nawet osoby, które niby znają się na kulturystyce pokazują czy opisują różne bzdury. Tak więc zacząłem jak ostatnio, na rozgrzewkę 40 kg plus sztanga. Dołożyłem akurat kolejne 10 kg, gdy poszedł ktoś z pytaniem czy może dołączyć. Było bardzo dużo ludzi, więc się nie dziwię, że nie znalazł wolnego sprzętu, także ochoczo się zgodziłem. Dla niego, na moje oko, był to jednak ciężar bardziej na rozgrzewkę (widać było po budowie, że już ćwiczy trochę), ale powiedział, że wystarczy, bo miał wypadek na nartach, więc dużych ciężarów nie potrzebuje. Nie potrzebuje, ale i tak założył w sumie 60 kg po chwili i pytał czy zdjąć, gdy przyszła moja kolej. No i jak to bywa w takich sytuacjach... ja nie dam rady? Potrzymaj mi piwo. Zrobiłem 5 powtórzeń z sztangą plus 60 kg, a moja twarz nabrała różnych odcieni purpury. Nic mi nie pękło i chociaż czuję mięśnie w odcinku lędźwiowym, to i tak jest lepiej niż po pierwszym razie z mniejszym o 20 kg ciężarem, gdy poprawiałem technikę. Tak, przy poprawnej coś sobie naciągnąłem i bolało mnie z miesiąc, hehe.


Dzień 19.

  Coś mi się przysnęło przedwcześnie, więc opisuje ostatni dzień rano dnia następnego. W sumie nie ma co pisać, bo dzisiaj nie było żadnych rewelacji. Rano z 1,5 h spędziłem na czytanie maili, komentarzy do kodu, wyjaśnienia i ustalenia z PM-em, typu czemu zrobiłem coś dynamicznie, skoro mówiłem, że statycznie będzie prościej. Okazało się, że dynamicznie też nie było tak źle, a senior powiedział, że jestem uparty i kto w sumie podjął decyzję o dynamiczności. Pokazałem to w kodzie i że nie pisałem tego godziny, a nawet gdyby, to i tak były to moje darmowe nadgodziny.

  Resztę dnia spędziłem na kolejnym zestawie zadań z nowego projektu. Dodanie nowego atrybutu do istniejącej klasy, migracja, a później wykorzystanie go w kontrolerach i widokach. Na końcu okazało się, że zrobiłem refactor i cofnąłem połowę zmian, bo znalazłem abstract controller, gdzie ten kawałek kodu pasował. Kolejna poprawka to jakieś filtry i do tego też jest osobna encja, w której musiałem dodać nowy atrybut, migrację itd. Tym razem znowu trochę mieszania w back-endzie i we froncie, bo jak czegoś nie widzę, to znaczy że muszę szukać w kontrolerach javascriptowych. Coś mi się tam sypało z wyświetlaniem, ale to przez ślepotę i ręczne pisanie getterów i setterów zamiast skorzystać z PHPStorma, który by to zrobił za mnie. Wolę na razie, żeby nie zrobił, bo później nic nie będę umiał napisać bez IDE. Poprawki w filtrze zadziałały, poprawki w wyświetlaniu też, tylko aplikowanie tego filtra z nowym atrybutem jakoś nie działa, więc nad tym będę siedział od rana dnia następnego. Nie skończyłem też dwóch ostatnich podpunktów, więc to też plan na jutro.


P.S. Mój główny architekt gra w Arkadię, jeżeli czytają mnie znajomi arkadyjczycy. :)

sobota, 25 marca 2017

Weekend

Sobota

  Z okazji weekendu, wszedłem sobie do wanny, do której zabieram tablet, gdzie mam jakieś apki z kursami, żeby poszerzać wiedzę. Pomyślałem, ze dokończę kurs z jQuery, który przyda mi się jako powtórka i oto efekt:



  Szkoda, że tydzień temu byłem w weekend zajęty poprawianiem strony fundacji i nie skończyłem tego kursu, bo przydałby mi się w minionym tygodniu i nie musiałbym się zastanawiać i szukać rozwiązań, które i tak znałem, ale gdzieś uciekły z głowy.

Niedziela

  Po męczącej sesji jogi, obiedzie, drzemce i kolacji, postanowiłem zajrzeć do projektu, który rozpocząłem jakiś czas temu. Google przysponsorował parę tysięcy miejsc na podstawowym kursie Androida i udało mi się na niego dostać. Trochę to ostatnio zaniedbałem, bo miałem braki czasowe, a teraz mając pracę to już tym bardziej. Do końca kursu zostały 2 tygodnie i pewnie nie zdążę zrobić aplikacji końcowej ani wykazać się aktywnością, za którą mają nagradzać awansem do dalszego etapu kursu, ale przynajmniej zrobiłem drugą "aplikację", która jest wymagana. Nazywają to "single screen app", ale ciężko to nazwać aplikacją, bo w zasadzie jest to front-end napisany w XML-u, no ale to dopiero początki. Także zrobiłem aplikację typu business card dla mojej fundacji i nawet udało mi się zrobić klikalne linki z numerem telefonu i adresem strony. Adres niestety nie przenosi do map, ale pewnie się kiedyś dowiem jak się to robi.



Następny rozdział kursu to robienie aplikacji interaktywnych, więc zobaczymy co mają na myśli, po jakiekolwiek wstęp do programowania zaczyna się dopiero w następnych lekcjach, które wcześniej nie były dostępne dla kursantów, ale znalazło się tam dużo ludzi, którzy skończyli cały kurs w tydzień albo dwa, bo wcale nie byli początkujący, co widać po ich kodzie, a kurs był zaplanowany na ponad 3 miesiące.


P.S. Ktoś mi na forum kursu podsunął rozwiązanie, które składało się z jednej zmiany po stronie XML-a i dopisanie prostej klasy do MainActivity.java i teraz po kliknięciu adresu, otwiera się mapa Google z tym adresem, więc fajnie. :)


Dzień 18.

  W piątek byłem już tak zmęczony po pracy, w której znowu siedziałem z godzinę dłużej, że odłożyłem napisanie tej relacji o jeden dzień, bo wczoraj już mi oczy krwawiły, mimo że je zakrapiam od chyba 2 tygodni. Smogu nie ma (do tej pory na niego dość mocno reagowałem), ale coś musi być w powietrzu, bo mam zapalenie spojówek, a kurz w pracy mi też nie pomaga. Niby przychodzi tam raz na tydzień jakaś pani, która przeleci mopem podłogę, ale zaczynam odczuwać szczypanie na dłoniach, a to już znak, że stężenie kurzu przerasta mój tolerowany poziom.

  Dzień w pracy zaczął się od tego, że musiałem uzupełnić coś, czym miałem się przedtem nie przejmować, czyli statusy dnia, które czyta prezes. Oczywiście wypatrzył, że ode mnie nie dochodzą, więc były jakieś podniesione głosy wczoraj, więc dzisiaj się dowiedziałem jak to ma wyglądać i uzupełnić "wpisy" za miniony tydzień. I tutaj z pomocą przyszedł mi swój własny blog, bo szybciej mi przypomniał co robiłem, niż gdy miałbym to wygrzebać z głowy albo z GitLaba. Od tego drugiego zacząłem, ale nie potrafiłem na szybko odnaleźć potrzebnych mi informacji, więc przeskoczyłem do czytania bloga i szybciej poszło. Tego się nie spodziewałem, ale byłem zadowolony, że po raz pierwszy mi się przydał, a liczę, że jeszcze się to powtórzy, gdy będę szukał jakichś rozwiązań, które tu opisałem.
  Następnie było już jako zawsze. A w sumie to gorzej niż zawsze, bo tym razem nad analizą siedziałem z 5 h, a kodowałem pewnie przez 2 h i to przy pomocy kolegi, który znał ten projekt. Po paru godzinach analizy, zaciąłem się w jednym miejscu, więc mi podpowiedział co gdzie jest, bo pamiętał. Znowu trochę rozgrzebałem, ale okazało się, że to co na "papierze" wydaje się proste, bo tylko dodanie wyświetlania jednej linijki tekstu, od strony back-endu wymagało poważniejszych zmian. W zasadzie była to nowa funkcjonalność, bo stara, podobna wykorzystywała trochę inny mechanizm i ponoć ma być usunięta. Ja musiałem dopisać nowy end-point i minimum poprawek we front-endzie (tekst plus odpytywanie back-endu co 10 s o aktualizację stanu). Do tego chwila testu, czy działa i czy czasem event nie przenosi się w inne miejsca, bo ponoć się tak zdarza, gdy strona nie jest przeładowywana, tylko odświeżana dynamicznie. W poniedziałek dopytam, czy zostawić ten tekst jaki jest, coś ostylować, czy przekazać do dalszej pracy dla front-endu.

  Przy okazji ciekawostka, bo nie do końca byłem pewien co do pisowni jednostek miar po liczbach, gdyż najczęściej zdarzało mi się je sklejać z liczbą, ale gdy napisałem "co 10 s o" zaczęło mi to brzydko wyglądać. Brzydko, nie brzydko, ale poprawnie co można sprawdzić tutaj.

czwartek, 23 marca 2017

Dzień 17.

  Dzisiaj klasycznie, 3 albo 4 godziny grzebania w projekcie, żeby znaleźć jakąś pierdołę, której poprawienie zajęło chwilę. Przy okazji, próbowałem rozwiązać ze dwa inne znalezione po drodze problemy, ale było jak zawsze, że nie było tego w zleceniu, to może później się tym zajmiemy. Moja zmiana miała coś zmieniać w jednym widoku, ale fakt, że było to w metodzie __toString() obiektu, wpłynie też na inne elementy projektu, więc szukałem trochę czasu kogoś do pomocy i przegadania, co z tym dalej. W efekcie, poprawkę wysłałem wraz z merge requestem, ale jeszcze jutro mamy testować.
  Grzebiąc w projekcie wynajduję coraz to nowe problemy, więc albo rosnę na testera, albo mnie wyrzucą z pracy. ;) Kolejna zaproponowana przeze mnie zmiana i chęć sprawdzenia czegoś jak wygląda "na produkcji" skończyła się niby pochwałą za pomysł, ale i kolejnym odkładaniem w czasie. Muszę się chyba nauczyć, że jak widzę jakiś problem, to nie naprawiam go od razu, tylko odkładam na później. Nawet mi Project Manager powiedział, żebym sobie założył zeszycik z odkrytymi błędami i je później zgłaszał...
  Może i to zabawne, ale chwilę później, gdy chciałem sprawdzić jedno podejrzenie co do skryptu odpalanego z crona, wywaliła mi się aplikacja. Po drodze usunąłem brancha, który został zmerdżowany (rany, nawet nie wiem jak to słowo napisać w polglishu), ale zrobiłem pulla na głównej gałęzi wraz z moimi poprawkami wcześniejszymi, więc powinno działać. Znowu się zastanawiam co źle zrobiłem, że się projekt wywala. Paczam sobie na procesy i load w systemie i cos jest nie tak. Restartuję apache'a, ale nie pomaga. Restartuję apache'a i mysqla i coś się poprawiło. Powtarzam test z mniejsza ilością danych i jest ok. Zaznaczam trochę więcej i znowu się coś sypie. Zaglądam do logów Symfony, a tam coś cały czas mieli, chociaż zamknąłem aplikację. Sprawdzam rozmiar a log ma już prawie 180 MB. Znowu jakieś restarty i teraz wrzucam terminal z logiem na drugi monitor i powoli klikam. Kliku klik i jeb! Znowu mi sypie jakimiś śmieciami na ekran i muszę restartować serwisy. Gdzieś tam dojrzałem rosnące cyferki i zaczęło mi to pasować do id obiektów w bazie. Wracam do front-endu i przyglądam się checkboksowi "zaznacz wszystko". Skoro na stronie jest paginacja i wyświetla się tylko 10 pozycji na raz, to taki checkbox do zaznaczania wszystkiego, jak do tej pory zaznaczał mi wszystko, ale na danej stronie. Tutaj się przyglądam uważnie i widzę tekst o liczbie zaznaczonych pozycji. Liczba ponad 42000 w chwilę uświadamia mi, co się zaczęło dziać z moją bazą i webserwerem. Napisałem do PM-a z pytaniem, czy klient jest świadomy co się dzieje po kliknięciu tego checkboksa i że grozi to katastrofą.
  Oczywiście wszystko mi się zaczęło sypać w momencie, gdy miałem się zacząć wdrażać w nowe zadanie i znowu szukać co i gdzie się dzieje w tym projekcie... Wyłączyłem komputer i poszedłem w cholerę, bo znowu coś się sypie nie z mojego powodu, a ja się martwię, że to moje zmiany coś popsuły...

  Nieco wcześniej, na przerwie w kuchni, rozmawiałem z nową koleżanką i okazało się, że kończyliśmy ten sam kurs programowania, tylko ona nieco wcześniej. Jednak jej szukanie pracy prawie nic nie zajęło i praca ją sama znalazła tuż po kursie, a mnie zajęło to parę miesięcy. Co ciekawe, pracowała w firmie, która i do mnie się odezwała, tylko niestety mnie nie proponowali stanowiska programisty, więc im podziękowałem. Może nawet tak źle nie wyszło, bo koleżanka nie była z nich zbyt zadowolona.

  Ze spraw przyziemnych, a więc nie związanych z programowaniem, przewróciłem się na schodach do metra i nie wiem jak to się stało. Posiedziałem chwilę zamroczony, zastanawiając się, co się właściwie wydarzyło i czy mogę się ruszać, ale otrzepałem się i poszedłem dalej. Pomogła mi jedna kobieta, bo reszta ludzi mnie po prostu ominęła. Pewnie to normalne, że nagle w połowie zejścia ktoś siada na dupie. Być może to kwestia pogody i ciśnienia, bo słyszałem takie doniesienia, a w pracy, gdzie muszę wchodzić 2 piętra po kręconych schodach na górę do wieży programistów i schodzić tyleż samo do kuchni, też miewałem dzisiaj wrażenie, że jakoś niepewnie się czuję, chociaż na co dzień śmigam po tych schodach dziarskim krokiem w ramach ćwiczeń fizycznych.
  Miałem też w pracy sytuację, która mnie wkurzyła, bo mi zawracali dupę w momencie, gdy miałem głowę pełną ośmiornicy kodu, a senior widząc moje wkurzenie, postanowił mnie rozbawić przysyłając zdjęcie uśmiechniętego kotka. Nosz, Kumar jego mać, nienawidzę zdjęć kotów w internecie! Humor mi się poprawił dopiero, gdy zrobiłem kawałek swojego zadania, a gdzieś kątem ucha usłyszałem rozmowę seniora z PM-em o planowaniu pracy oraz że juniorzy sobie na razie nieźle radzą, więc puściłem porozumiewawcze spojrzenie i 2 x 👍 do drugiego miniona, erm, juniora, a w sumie juniorki.

PS. Znienawidzone kocisko od seniora wygląda tak. Nie, nie dawaj lajka!



środa, 22 marca 2017

Dzień 16.

  Rozpocząłem od grzebania w back-endzie, bo już wczoraj wiedziałem mnie więcej gdzie. Poprawka była w miarę prosta, bo polegała na zmianie repozytorium, z którego będą pobierane dane. Przeklikałem trochę, żeby sprawdzić czy działa przenoszenie między różnymi obiektami, a przy okazji znalazłem jakiś błąd, który zgłosiłem i będzie do naprawienia później, poza oficjalnym zamówieniem klienta. A znalazłem błąd dlatego, że myślałem, iż to moja poprawka coś popsuła, a tym czasem problem jest gdzieś indziej i nie aktualizuje się jedno pole, mimo iż powinno być puste. W ten sposób nie mogłem odnaleźć swojego obiektu wpłaty, który był przenoszony do innego rodzaju darczyńcy. Nagle ślady po tych wpłatach były w 3 innych obiektach, a ona sama była tylko w jednym. Wiedziałem już, że to nie moja wina, więc przestałem się na razie przejmować, a kolega na Slacku zasugerował, w której metodzie może być błąd.
  Nadszedł czas próby, a więc kolejny typ obiektu, gdzie ostrzegano mnie, że wpłaty dla niego są inaczej rozwiązane. Oczywiście okazało się, że po przeniesieniu obiektu wpłaty do tegoż obiektu darczyńcy, zaczęły się problemy z wyświetlaniem, a "zły duch Symfony", jak nazywam tego duszka, który wyskakuje podczas błędów pokazał mi, że brakuje jednego pola. Sprawdziłem co i jak i poprosiłem o poradę techniczną. W międzyczasie było krótkie spotkanie statusowe z PM-em i zaraz później poszliśmy do głównego architekta, żeby przedstawić problem i pogadać o rozwiązaniach. Skończyło się wymuszonym ustawianiu tego pola na wartość 1 przy przenoszeniu w jedną stronę, a w drugą zachowywała się automatycznie. Problem rozwiązaliśmy (bo sam tylko kawałek napisałem) w sposób taki, że sprawdzaliśmy czy obiekt przenoszony jest (a w zasadzie to !jest) instanceof obiektu rozszerzonego i jeśli nie był to tworzyliśmy obiekt rozszerzonego typu, gdzie po zmianach w jego konstruktorze robiliśmy kopię obiektu podstawowego (rozszerzony dziedziczył po klasie podstawowej) i dodawaliśmy na sztywno ustawione na 1 wspomniane dodatkowe pole. Troszkę mi się "pozajączkowało" (pojęcie autorstwa mojej polonistki z podstawówki) przy tym kopiowaniu atrybutów, bo było ich sporo i skopiowałem o jeden za dużo, dzięki czemu wpłaty uległy cudownemu rozmnożeniu, ale nie było z nimi żadnych relacji z darczyńcą, więc pieniądze niejako spadły z nieba, a już szczególnie, że to projekt dla klienta, który jest organizacją katolicką zajmującą się redystrybucją donacji. :)

  W międzyczasie jeden kolega chciał skorzystać z moich skilli administracyjnych, bo zainstalował wreszcie Linuksa, tylko coś mu nie działało wchodzenie do MySQL-a na konto roota bez hasła. Ja na szczęście od razu ustawiłem sobie hasło, bo już widziałem jak się kończy domyślne ustawienie braku hasła na koncie roota w MySQL-u. W domu też musiałem walczyć z tym, że przy domyślnej instalacji było coś nie tak, więc już swoje zmarnowałem na grzebanie po sieci. U mnie skończyło się to przestawieniem jakiegoś pluginu do autentykacji, tyle że ja mogłem się do swojej bazy zalogować, a kolega nie bardzo. Jako, że to była świeża instalacja i nie miał tam żadnych danych, postanowiłem spróbować innego sposobu. Odinstalowałem wszystkie paczki mysql-server-*, mysql-common z opcją --purge, usunąłem /etc/mysql/ oraz przede wszystkim wszystkie bazy z /var/lib/mysql. Po tej operacji ponowiłem instalację paczek mysql-server*  i wtedy, gdy pojawiło się okienko z pytaniem o hasło roota, kazałem mu na moich oczach coś tam ustawić, a później sprawdzać czy może się logować na konto roota w MySQL ze zwykłego konta użytkownika przez: mysql -uroot -p. Na szczęście zadziałało i więcej o nic nie pytał.
Gdzieś tam po drodze odezwał się jeszcze inny kolega, który również miał problemy, ale jemu się udało dodać zwykłego użytkownika i jakos mu to działało. Wspomniał coś o "jakichś tam socketach", ale nie wiedział bardzo o co chodzi. Ten pierwszy, który mnie prosił o pomoc też przeczytał o socketach, ale też nie rozumiał czego od niego chcą. Okazuje się, że można być programistą i nie wiedzieć co to socket. Wyjaśniłem na szybko, a w razie czego sobie doczytają, skoro nie zastanawiali się nigdy jak ten mysql-client z terminala działa, skoro nie podają numeru portu. Z resztą, może nigdy  nie pisali kodu, który musiał się łączyć z bazą na innej maszynie, tylko wszystko było lokalnie.

  Skończyłem poprzednie zadanie z przenoszeniem między różnymi obiektami i wziąłem się za nowe w tym samym projekcie. Klasyczne zadanie typu "zajmie Ci to góra godzinę, bo to prosta poprawka w wyświetlanym formacie". No pewnie, to zawsze są proste zadania, a później się okazuje, że żeby wygenerować PDF-a, muszę odpalić specjalnie dopisany skrypt do symfoniowego app/console i jakimś cudem ten skrypt się wywala i wypluwa z siebie losowe zipy. Także zanim się zaczęło grzebanie w zadaniu, trzeba było przejrzeć skrypt, posprawdzać gdzie przestaje działać (die("Boom!");) i rozgryzać co się stało, skoro wszystko pasuje do dokumentacji tej biblioteki. Ktoś gdzieś w sieci napisał, że też miał taki błąd przy aktualizacji do php5.6, ale jego rozwiązanie zupełnie tutaj nie pasowało. Zrobiliśmy wreszcie jakiś quickfix, który zadziałał, ale bez rozumienia czemu tak się w zasadzie dzieje, bo tu by już trzeba było głębiej grzebać w bibliotece, a na to już było późno, bo i tak nadgodziny robiliśmy powoli.

  Na koniec jeszcze czekała mnie poprawka w README.MD od tego projektu i skoro poprzednią zrobiłem przez interface www GitLaba, to teraz chciałem zrobić to samo (na GitHubie tak robiłem, bo było szybciej i był od razu podgląd czy markdown dobrze działa). Usłyszał to architekt i powiedział, żebym więcej tak nie robił, bo kiedyś coś im się tak rozsypało i że mam to robić lokalnie, a w PHPStormie mam podgląd i powinno wystarczyć. Średnio wystarcza, bo podgląd tabelek nie działa. No ale zrobiłem to lokalnie. Tylko, że bezpośrednio w gałęzi develop, bo nie chciałem w tym celu robić oddzielnego brancha i merge requesta. Po wykonaniu pusha, ze zdziwieniem zobaczyłem, że nie ma znanej mi już informacji, że mam kliknąć w link i zgłosić merge request. Jutro czekam na komentarz, że nie pracujemy na gałęzi develop i jestem niegrzecznym chłopcem. O 19.30 i informacją, że za 10 minut wszyscy mają wyjść z firmy, już ciężko się myśli i pamięta o rzeczach, do których jeszcze nie ma się wyrobionych nawyków.


wtorek, 21 marca 2017

Dzień 15.

  Zaczęło się poważnie, bo na firmowym Slacku napisał do mnie senior, który dzień wcześniej się znowu próbował ze mnie nabijać. Napisał, że absolutnie nie próbuje powiedzieć, że jestem głupi i że to wszystko żarty, ale jeśli mnie obraził to przeprasza. Odpowiedziałem, że znam się na takich żartach i sam się wychowywałem wśród ludzi, którzy nieustannie sobie docinali, ale wszyscy wiedzieli, że to nie jest do końca złośliwe, tyle że z czasem takie zachowania wchodzą w krew, więc staram się tego od wielu lat oduczyć, bo czasem takie żarty trafiają na przewrażliwionych ludzi i robi się przykro. Na koniec dodałem, żeby się nie przejmował, bo nikt kto nie umie nagrać płyty DVD nie jest w stanie mnie obrazić. :>

  Od rana grzebałem w nowym projekcie, który dostaliśmy dzień wcześniej. Znowu jakaś pierdółka, typu trzeba dodać <select> z jakimiś opcjami i to oczywiście jest proste, tylko przebicie się przez Symfony i znalezienie zależności znowu zajęło mi ze 2h. HTML-a ogarnąłem w miarę szybko, ale już dynamiczną obsługę tego okienka musiałem trochę pomęczyć, bo JS i jQuery uczyłem się przez tydzień, plus napisanie projektu, który to ze sobą łączy przez RESTful API. Zajrzałem do swojego kodu z tego projektu i oczywiście tam było wszystko jasne, a tutaj ponownie zastanawiałem się co się dzieje i jak te parametry są przekazywane. W międzyczasie było spotkanie statusowe z PM-em i jakoś chwilę później mnie olśniło jak to wszystko ma działać. Znowu doszedłem do etapu, że 3h analizy i 2 linijki kodu... Resztę czasu spędziłem na poprawianiu widoków dla pozostałych obiektów i trochę zabawy z jQuery, żeby ustawiać <option> w zależności od encji, dla której jest wyświetlany widok. Najpierw zrobiłem w prosty sposób, ale w międzyczasie PM wpadł na pomysł, że tak będzie fajniej, więc musiałem poprawiać poprzedni kod. Zrobiłem pewnie ponad 10 commitów do repozytorium.

  Porobiłem trochę testów i wszystko działało. Poza back-endem, no ale tego się można było spodziewać. Zajrzałem do opisu zadania i było tam wspomniane gdzie szukać problemów, więc jutro od rana pewnie będę w tym grzebał, ale na razie doczytałem, że jeszcze jedną rzecz we froncie trzeba zrobić (czyszczenie drugiego inputa z wynikami wyszukiwania, jeśli zmieniła się wartość w pierwszym okienku). Kawałek napisałem, poprawiłem poprzedni kod, żeby nie dublować zapytań przez jQuery i nagle słyszę swoje imię, ledwo przebijające się przez muzykę w słuchawkach. Zdejmuję i pytam o co chodzi. Padło pytanie czy do mnie dotarło, że za 2 minuty wychodzimy z pracy. No więc cóż, znowu musiałem zostawić rozgrzebany kod, ale już raczej niewiele w tym froncie zostało. Dobrze, że podszedł do mnie ze 2 lub 3 razy w ciągu dnia, kolega który dużo w tym projekcie napisał, więc mi wskazał parę miejsc i nie musiałem się przeklikiwać przez dziesiątki plików. On też rozwiązał mój problem, czemuż to zmiany w kontrolerze po stronie JS nie chcą mi działać. Padło magiczne hasło Gulp i konieczność jego instalacji (lecz oczywiście najpierw NodeJS, żebym mieć npm, żeby mieć Gulpa.. Doh!) oraz odpalania po każdej zmianie w plikach .js. Trzeba będzie poczytać o Gulpie, chociaż na razie wystarcza mi wiedza, żeby go uruchamiać po zmianach, a on już resztę sam zrobi.

Gulp oczywiście nie zadziałał ot tak od razu, mimo instalacji z repozytoriów Ubuntu. W skrypcie uruchomieniowym była linijka:
 #/usr/bin/env node
a w systemie binarka od NodeJS, nazywała się... nodejs, więc musiałem ręcznie ten skrypt poprawić. Gdybym nie miał linuksowego doświadczenia, pewnie znowu bym przeklinał, że cos nie działa. Ot tak jak koledze wczoraj przestał wstawać system. Podchodzę a tam busybox i initramfs. Pytam co zrobił, że doprowadził do takiego stanu, a on na to, że tylko dropa bazy w MySQL-u. No to grzebię tam i patrzę, uszkodzony system plików, więc naprawa, restart i działa. Nie wiem jak drop bazy może wysypać filesystem, ale jak widać wszystko jest w tych czasach możliwe. Poszedłem się coś napić, wracam, a kolega, że teraz sieć mu nie działa. No, psia mać, samo z siebie? Koniec końców mu to naprawiłem, ale dziwne rzeczy się tam działy i może nie do wszystkiego się przyznał co robił. 

Miałem tu być w końcu programistą, prawda? ;)

PS. Zwolennikiem Linuksa w wersji serwerowej i tak pewnie długo jeszcze zostanę, ale udało mi się zrobić takie ciekawe zdjęcie w autobusie:


Oczywiście chodzi o tablicę z rozkładem jazdy, która się popsuła i prosi o naciśnięcie dowolnego klawisza, a nie o blondynkę, ale każdy tu znajdzie coś dla siebie.


poniedziałek, 20 marca 2017

Dzień 14.

  Rano próbowałem pogrzebać we front-endzie jednego projektu, ale trochę zapomniałem jak się pisze pewne rzeczy, więc za długo mi to szło. Dostałem polecenie, żeby to już olać i zająć się nowym projektem. Wrzucono mnie i nową koleżankę do nowego projektu, więc było spotkanie z PM-em, który opowiadał co i jak, aż zrobiła się 13.00. Koleżanka dostała klasyczne zadanie, czyli "zainstaluj sobie system, niech będzie to Linux Mint 18", więc tylko czekałem w napięciu aż coś się zacznie sypać. Zaczęło się dosyć szybko, bo już przy próbie bootowania świeżo nagranej płyty (żeby nie było, że znowu cos nie tak z pendrive'em itd.). Zajrzałem tam, nie startował nawet GRUB, więc powiedziałem, że za te podśmiechujki głównego architekta, że nie umiem zainstalować sobie Linuksa, ja się teraz będę śmiał, że on nie umie nagrać płyty. Coś tam w międzyczasie kombinowali z przepinaniem zewnętrznego napędu, aż w końcu ruszyło, bo zawołali mnie, żebym pomógł przy podziale na partycje. Pomogłem, zainstalowało się. Podszedłem sprawdzić jak wygląda pierwsze uruchomienie i było ok, Cinnamon się nie zawiesił. Na wszelki wypadek kazałem jej zrestartować parę razy komputer, bo u mnie to raz działało a raz wisiało. U niej zadziałało kilkukrotnie, więc mogła sobie doinstalowywać inne rzeczy. W tym komputerze była inna płyta główna niż w tych, w których mieliśmy problem i inna karta graficzna. Może jeden z tych elementów wpłynął na to, że tym razem instalacja i działanie było bezproblemowe. Poza pierwszym bootowaniem płyty instalacyjnej, ale później pan architekt mówił coś, że ta płyta chyba się źle nagrała, więc dopiąłem swego i przedrzeźniałem go, że nie umie nagrywać płyt. Teraz już zawsze będę tak odbijał piłeczkę, jak usłyszę, że taki ze mnie mechanik od mercedesów a z maluchem sobie nie mogłem poradzić!

  Od dzisiaj też pewnie będą śmichy-chichy ze mnie i ekspresu do kawy, bo nawet prezes podjął temat i mi docinał, że niezły buffer overflow zrobiłem. Do tej pory, gdy parzyłem kawę (Jessicka jest wiecznie poza pracą i tylko stoi jej puste krzesło i komputer przy wejściu), wsypywałem dwie zawartości młynka do ekspresu (ręcznie mielimy kawę, bo ekspres z tych tańszych) , bo jedna byłaby raczej za słaba, ale nie był to pełny młynek. Kolega, który był przy mnie powiedział, że zawsze widział, ze ludzie wsypują do młynka kawę z usypaną górką. No to zrobiłem z górką. Szkoda, że chwilę później mnie wołali na dół, że coś stało się z ekspresem. No cóż, ulało się trochę temu ekspresu i musiałem sprzątać. Później się dowiedziałem, że ten młynek z górką usypaną z kawy, który "ludzie robią" to był tylko jeden... :)

  No nic, po obiedzie w postaci kebabu i sprzątaniu kuchni, wróciłem wreszcie do zajęć programistycznych. Ściągnąłem projekt i zależności, uruchamiam i od razu error do kolegi Ajaksa. Zaglądam, a biedaczek ma jakieś kłopoty z bazą, którą wcześniej wgrałem (gdy już dostałem z zewnątrz, bo ta w builderze projektu się sypała przy imporcie). O dziwo, dane się wyświetlają, ale i tak co chwila error. Sprawdzam o co chodzi, a tam nie podoba mu się (w sumie to nie Ajaksowi tylko back-endowi) grupowanie danych przy selectach. Pytam wokół czy ktoś coś i architekt na hasło "strict" kojarzy, że była jakaś zmiana w MySQL-u. No więc szukam zmiany, stosuję i poprawiam readme.md w projekcie. Okazało się, że w wersji 5.7, którą mam wraz z system zmieniono pewne rzeczy, a jak je sprytnie odmienić, najlepsze rozwiązanie znalazłem tu:

How to Disable Strict SQL Mode in MySQL 5.7

  Dobrałem się wreszcie do projektu, przejrzałem trochę plików i akurat podszedł kolega, który ma być dla nas supportem w tym projekcie i momentalnie mi wskazał, gdzie w encji są ograniczenia, których szukam. Wcześniej tego na oczy nie widziałem, więc pewnie nawet bym tam nie zajrzał, także kolejna ciekawostka w moim rozwoju. Poprawiłem encje, "popsułem" bazę, bo były constrainty i zaczęło działać. Teraz tylko wypadałoby to zrobić zgodnie ze sztuką, więc potrzebowałem diffa do migracji bazy i tutaj miałem kolejną niespodziankę, bo wygenerował się pusty. Miałem więc okazję, żeby pobawić się różnymi komendami php app/console doctrine:migration:xxx i zobaczyć jak to działa, bo do tej pory używałem tylko doc:schema:update. Przy okazji dowiedziałem się, że można operować skrótami komend w konsoli Symfony. Gdy dostałem pierwszy raz info od seniora, żeby zrobić doctrine:mig:mig -n, pomyślałem że po prostu nie chciało mu się pisać doctrine:migration:migrate, ale kolega powiedział, że można nawet d:m:m napisać, ale mig:mig jest zabawniejsze i łatwiej zapamiętać. Zaczęło się od tego, że polecił mi komendę app/console d:d:d, ale nie sprawdzaj jej, drogi Czytelniku! To taka sama zła komenda, jak w jednym mądrym poradniku o pisaniu skryptów w Bashu, gdzie jako przykład użycia przełączników podano komendę: rm -rf /. Autora tego poradnika, ktoś powinien mocno uderzyć w głowę...


P.S. Nowej koleżance poleciłem od razu instalację PHP w wersji 5.6, poza 7.0, który jest z systemem, bo trafi tak jak ja na starszy projekt i będzie się zastanawiać co się dzieje. Wystarczy, że teraz jej projekt nie ruszał, a to była tylko kwestia uprawnień do cache'a i logów. Polecana wersja i repozytorium znajduje się tutaj:

Ondřej Surý

Przy okazji podmieniłem domyślną wersję PHP w systemie:

update-alternatives --set php /usr/bin/php5.6

Pamiętać też należy, żeby przełączyć moduły w Apache'u. Teraz robi się to przez:

a2dismod php7.0 oraz
a2enmod php5.6

Można też ręcznie bawić się z symlinkami, ale w sumie powoli przekonuję się do używania tych komend.

Skończę ten wpis i zaraz to samo robię na domowym systemie, żebym nie miał niespodzianki jak przyjdzie pracować zdalnie.

niedziela, 19 marca 2017

Dzień 13.

  Wreszcie udany dzień! Raz tylko zaczepiłem seniora o jakąś bzdurę. Napisałem od razu dobrze metodę do pobierania danych, ale błąd był gdzie indziej (literówka). Grzebiąc i kombinując poprawiłem dobrze napisany kod na źle i dalej już poszło. Senior mi wycofał większość zmian, wróciliśmy do mojego kodu z początku i działało. Znowu mi się głupio zrobiło, ale przynajmniej teraz kojarzyłem, że problemem była literówka w konstruktorze tej metody w innym pliku.
  To był jeden z czterech podpunktów tego zadania, a dalej poszło już całkiem zgrabnie. Dodanie nowego atrybutu do encji (to co parę dni temu musiałem cofać) i poprawka w formularzach do edycji danego zlecenia, wraz z testami czy to dobrze działa z każdego miejsca tego CRM-a.
  Ostatnim elementem była poprawka w kodzie, który zaznaczone obiekty z formularza eksportował do formatu Excela. Tu znalazłem 4 pliki pisane przez kolejnego kolegę z firmy, bo tam się dużo nazwisk przewija w komentarzach, więc każdy się już z tym męczył w pewnym momencie. Ten fragment wymagał ode mnie głównie obejrzenia pliku wynikowego i dodaniu odpowiednich kolumn w plikach do konwersji.
  Została jeszcze jedna rzecz do omówienia, ale zostawiliśmy to na później, bo ten projekt, który miał się skończyć tydzień temu i wreszcie miał być czas dla mnie, jakoś uparcie nie chce działać i się skończyć. Także pozostała mi jeszcze zabawa z JS, który będzie dynamicznie zmieniał pola w tych formularzach, ale to po dogadaniu szczegółów z seniorem, bo już raz się źle zrozumieliśmy i jak w tym słynnym obrazku, klient chciał huśtawkę a ja mu zacząłem robić karuzelę. :)



  Nie znalazłem tego obrazka w wersji z karuzelą, ale ten przedstawia problem.



Dzień 12.

  Ciągnie się za mną ten nieszczęsny projekt ze źle nazwanymi encjami i jeszcze gorzej tabelkami, które je reprezentują. Po co nazwać tabelę w bazie tak samo jak encja, skoro można dodać coś od siebie, albo przestawić kolejność słów. Udało mi się wreszcie dokończyć jedno z zadań. Metoda jeszcze wczoraj działała, a dzisiaj przestała. Senior naprowadził mnie na przyczynę. Okazało się, że przestało działać, bo zmieniłem branch, gdyż miałem dwa rozgrzebane i cofnęły mi się zmiany w kodzie, a nie wszystkie nadpisałem...

  Później dostałem dość proste zadanie (pewnie 15 minut dla kogoś, kto ogarnia), ale mnie zajęło ze 3h, z czego godzinę doinstalowywałem php5.6 i je konfigurowałem, bo projekt z php7 domyślnie zainstalowanym z systemem, po prostu nie działał. W zadaniu miałem wyłączyć jeden punkt api i w to miejsce wstawić odpowiedź w jsonie z paroma danymi. W sumie banał jak na to patrzę po fakcie, ale z głowy bym nie napisał, a dokumentacja i Stackoverflow zawiódł ponownie. Później znowu wróciłem do "ulubionego projektu", gdzie miałem rozgrzebane zadanie. I już prawie witałem się z przysłowiową gąską, ale kazali mi iść do domu, bo wychodziła ostatnia osoba, która ma klucze do firmy. Jak patrzę ile czasu mi takie pierdoły zajmują, to mam nadzieję, że już niedługo będę się mógł z tego śmiać, że jak mogłem nie wiedzieć jak pobrać dane z obiektu, którego jeden z atrybutów jest kolekcją innych obiektów... Ale przy tak durnym projekcie i nazwach wszystkiego co się w nim znajduje może nie będę się śmiał, tylko jeszcze bardziej przeklinał niż teraz.

Dzień 11.

Znowu się zastanawiałem czy nie jestem na to za głupi, bo najpierw nie mogłem sprawdzić stanu checkboksa po stronie back-endu znanymi mi i znalezionymi w sieci sposobami, a później, gdy już dostałem rozwiązanie i się zawstydziłem, nie potrafiłem sobie poradzić z dokumentacją i innym problemem. Niby czytałem różne dokumentacje przez lata i jakoś to ogarniałem, a jednak dokumentacja do Symfony mnie zaskakuje. Co prawda, było to coś nowego, a więc korzystanie z QueryBuildera, czyli takiego niby ułatwienia zamiast pisania własnych własnych zapytań w DQL-u, ale wszystkie przykłady były na prostych obiektach (w materiałach z kursu też były podstawy, które pozwoliły mi tylko zacząć). Gdy doszło do zrobienia zapytania na dwóch encjach z dwoma warunkami to już się zapętliłem. W końcu mi senior pokazał jak się tam robi join na dwóch encjach, bo w rezultacie tego mi zabrakło, ale i tak mi było głupio, że poświęciłem ze 2 albo 3 godziny na 5 linijek kodu. Za to dowiedziałem się jak korzystać z var_dumpa w Symfony, tak żeby go sensownie podejrzeć, bo jakoś z kursu tego nie wyniosłem i pamiętam, że var_dumpy kończyły się białym ekranem. Okazało się, że w devtoolsach w przeglądarce trzeba zajrzeć do zakładki network i tam kliknąć w request, a następnie podgląd, bo Sf przy dumpie podczas POST-a, po prostu nic nie robi, jakby się nie kliknęło w przycisk w ogóle (przynajmniej w tym projekcie, bo tam jest ajax we front-endzie). To mnie bardzo uszczęśliwiło, bo wreszcie zobaczyłem co się dzieje z danymi, które obrabiam i nie jestem jak dziecko we mgle, które na oko coś tam programuje. Dzięki temu sprawdziłem czy poprawka pętli foreach, którą napisałem 2 dni temu, a która mogła przy większej ilości danych zalać pamięć, po zamianie na zapytanie w bazie w repozytorium danej encji, po prostu działa jak trzeba. To był drugi raz, gdy się tego dnia uśmiechnąłem i krzyknąłem: Niech żyje var_dump! A propos, zamiana var_dumpa na print_r, żeby ładniej wyglądało skończyła się tak, że przerywało mi muzykę, a podgląd w devtoolsach pojawiał się po 10 sekundach, więc trzeba na to uważać.