31 maj 2017

28 maj 2017

Automat do pobierania kursów funduszy - 12 tydzień konkursu Daj Się Poznać

Witajcie! W tym tygodniu znowu publikuję tylko jednego posta i to dopiero w niedzielę. Na szczęście tym razem mogę napisać, że powstało sporo nowego kodu. Udało mi się dokończyć i uruchomić automatyczne pobieranie kursów funduszy Nationale-Nederlanden oraz ich zapis w bazie - oczywiście za pośrednictwem API. Zatem dziś krótko o tym rozwiązaniu.

20 maj 2017

InfoShare 2017 - moje przemyślenia i wnioski

Konferencja InfoShare jest stałym punktem na mojej corocznej mapie wydarzeń - nie mogło mnie więc tam zabraknąć również w tym roku. Za każdym razem wynoszę wiele cennej wiedzy z prezentacji, w których mam okazję tam uczestniczyć. Dziś chciałbym podzielić się kilkoma tematami które rezonują w mojej głowie po tegorocznej edycji.

16 maj 2017

Portfel Emerytalny - 11 tydzień konkursu Daj Się Poznać

Przyszedł czas na kolejny update co dzieje się z prowadzonym przeze mnie projektem. Niestety podobnie jak w ubiegłym tygodniu nie powstało za wiele kodu. Stali czytelnicy pewnie zauważyli też, że w ubiegły czwartek/piątek nie pojawił się drugi z cotygodniowych postów. To wszystko dlatego, że zrobiłem sobie mały urlop i nie miałem za wiele okazji do kodowania.

Nie znaczy to jednak, że nie wydarzyło się zupełnie nic. Najważniejszą nowością jest nowy adres pod którym jest dostępna aplikacja: planujemeryture.pl. Od teraz będzie to podstawowy adres aplikacji, jednak na razie utrzymuję ją również w tej samej wersji pod adresem thorin87.github.io

Równolegle wystartował również fanpage na FB: www.facebook.com/planujemeryture. Na razie jest tam bardzo ubogo i nie ma nawet żadnego polubienia. Będę tam wrzucał aktualizacje co dzieje się z aplikacją, być może też co nieco o oszczędzaniu na emeryturę - jeśli temat jest dla Ciebie interesujący to zapraszam do "lajkowania".

Blog też przeszedł drobne zmiany. Po prawej pojawiły się odnośniki do aplikacji Portfela Emerytalnego oraz do profili w mediach społecznościowych. Poza tym dodałem brakujące tłumaczenia elementów szablonu i kilka innych kosmetycznych poprawek.

W samej aplikacji natomiast udało się popracować tylko nad automatem do pobierania danych, ale na razie bez efektów (jeszcze nie działa). Fundusze w bazie zyskały nowe pole ExternalId pod jakim są identyfikowane na stronach TFI, ale ze względu na małą ilość pozostałego do końca konkursu czasu na razie te Id zostaną wpisane na sztywno w kodzie automatu.

8 maj 2017

Portfel Emerytalny - 10 tydzień konkursu Daj Się Poznać

Cześć! Zapraszam na cotygodniowe podsumowanie tego, co dzieje się z moim projektem konkursowym.

W tym tygodniu nie udało się napisać zbyt wiele kodu, ale przemyślałem jak zoptymalizować zapytanie do bazy, które zwraca dane potrzebne do wyświetlenia wykresu. Będzie sporo przetwarzania wyników z bazy po stronie backendu, ale jednocześnie zapewnię możliwość wyboru, które fundusze są prezentowane na wykresie. Zacząłem już nawet zapisywać co wymyśliłem, ale na razie skończyło się na zakomentowaniu wszystkiego. Zapytanie które jest teraz zwraca dokładnie czego potrzebuję, więc jego optymalizacją zajmę się w przyszłości.

Kolejną rzeczą którą poprawiłem jest format JSON zwracany jako odpowiedź na zapytania do API. Wcześniej każdy wiersz wyniku był zwracany jako tablica, a teraz jest to obiekt z nazwami kolumn z zapytania. Czyli było tak:
{
  "data": [
    [
      1, 
      "IKE", 
      "IKE Plus", 
      "NN Investment Partners TFI S.A.", 
      "Towarzystwo funduszy inwestycyjnych"
    ], 
    [
      2, 
      "IKZE", 
      "Dobrowolny Fundusz Emerytalny PZU", 
      "PTE PZU SA", 
      "Powszechne towarzystwo emerytalne"
    ]
  ]
}
a teraz jest tak:
{
  "data": [
    {
      "Id": 1, 
      "Name": "IKE", 
      "Owner": "NN Investment Partners TFI S.A.", 
      "OwnerType": "Towarzystwo funduszy inwestycyjnych", 
      "ProductName": "IKE Plus"
    }, 
    {
      "Id": 2, 
      "Name": "IKZE", 
      "Owner": "PTE PZU SA", 
      "OwnerType": "Powszechne towarzystwo emerytalne", 
      "ProductName": "Dobrowolny Fundusz Emerytalny PZU"
    }
  ]
}
Po tej zmianie mogłem we frontendzie zmienić nic nie mówiące wywołania w stylu wallet[1] na opisowe wallet.Name. Dodałem też kilka klas (a konkretnie interfejsów) modelu we frontendzie, dzięki czemu do tego będzie działało jeszcze podpowiadanie składni dla tych obiektów.

To tyle jeśli chodzi o ubiegły tydzień, mam nadzieję że kolejny będzie bardziej obfity w nowy kod i funkcjonalności.

6 maj 2017

Portfel Emerytalny - podsumowanie kwietnia

Upłynął kolejny miesiąc konkursu Daj Się Poznać, pora więc na podsumowanie co się zmieniło i jaki jest teraz stan aplikacji Portfela Emerytalnego. Tym razem dużo łatwiej robić mi takie zestawienie, bo mam cotygodniowe raporty ze zmianami oraz listę celów, które wyznaczyłem sobie na kwiecień. Skonfrontuję je zatem ze sobą, poza tym zaplanuję co będę robił w maju.

Plan na kwiecień był podzielony na 3 główne obszary: aplikacja, promocja, blog. W trakcie miesiąca plan ten przeszedł drobną metamorfozę - aplikacja została zmieniona na tryb tylko do odczytu, o czym pisałem w podsumowaniu 8. tygodnia. Głównym celem w obszarze aplikacji było opublikowanie Portfela Emerytalnego online, co udało się osiągnąć - efekt można zobaczyć na https://thorin87.github.io/. Nie byłoby to jednak możliwe, gdybym chciał zrealizować wszystkie punkty z tego obszaru - stąd właśnie decyzja o rezygnacji z możliwości wprowadzania własnych danych. A co dokładnie udało się wykreślić z listy?
  • znaleźć i wdrożyć layout interfejsu użytkownika
  • zapisać w bazie kursy wszystkich funduszy których jednostki posiadam lub posiadałem (idealnie gdyby działał już automat aktualizujący dane)
  • zaimplementować operacje związane z portfelem inwestycji (kupno, sprzedaż, zamiana)
  • uzupełnić portfel o historyczne operacje które wykonywałem
  • wyświetlać listę posiadanych jednostek funduszy 
  • prezentować historię operacji
  • wyświetlać wykresy wartości posiadanych walorów (idealnie gdyby zaznaczały się na nim operacje z historii)
  • wyświetlać procentowy zysk/stratę ze wszystkich inwestycji (idealnie byłoby gdyby dało się wybrać z których)
Jak widać udało się zrealizować całkiem sporą część planu, a to czego nie udało się zrobić zostanie przeniesione na plan majowy - ale o tym za chwilę.

Zrezygnowałem też na razie z promocji na Facebooku. Uznałem, że skoro mam zakładać profil produktu, to lepiej będzie jeśli Portfel Emerytalny będzie już dostępny w sieci - przynajmniej w podstawowej wersji. Teraz już jest, więc profil na FB to kolejna rzecz która przechodzi na listę rzeczy do zrobienia w maju.

Ostatni obszar kwietniowego planu to zmiany na blogu. Ten punkt udało się wdrożyć w całości, co tydzień pojawiał się jeden post o zmianach w projekcie i jeden o tematyce bardziej ogólnej. Niestety nie udało się utrzymać regularnych publikacji w poniedziałki i czwartki, jednak ostatecznie w każdym z tygodni pojawiły się 2 posty i tego chcę się trzymać.

Plan na maj

W chwili pisania tego posta zostały jedynie 3 pełne tygodnie maja. Jeśli plan ma być realny, to nie mogę zakładać zbyt wiele rzeczy do zrobienia. Jak już pisałem na pewno chcę założyć profil Portfela Emerytalnego na Facebooku. Jeśli zaś chodzi o samą aplikację, to poniżej prezentuję listę funkcjonalności, które chciałbym żeby pojawiły się w maju:
  • uruchomić automat aktualizujący dane dla funduszy, których jednostki posiadam (dodatkowo zrobić research którymi funduszami zająć się później)
  • dokończyć profile użytkowników oparte o tokeny
  • dodać możliwość dodania do profilu portfeli IKE i IKZE
  • zaimplementować operacje w konkretnym portfelu (kupno, sprzedaż, zamiana jednostek uczestnictwa)
  • prezentować historię operacji w portfelach
  • dodać wybór, które fundusze są prezentowane na wykresie
  • zaznaczać na wykresie operacje z historii
Do pełni założonej na początku funkcjonalności będzie brakowało jeszcze analizy kursu funduszy przez kroczący stop loss i powiadomień o jego osiągnięciu. Patrząc na dotychczasowe tempo rozwoju prawdopodobnie nie uda się osiągnąć tego w maju. Wydaje mi się jednak, że ważniejsze jest udostępnienie możliwości zakładania własnych portfeli. Kroczący stop loss będzie zatem zaimplementowany w kolejnej wersji aplikacji, bo wierzę że rozwój Portfela Emerytalnego nie skończy się razem z końcem konkursu.

2 maj 2017

Portfel Emerytalny jest już online - 9 tydzień konkursu Daj Się Poznać

Ostatni tydzień rozwoju aplikacji był poświęcony jednemu celowi - spiąć wszystkie warstwy ze sobą i wystawić je online. Co prawda z małym opóźnieniem, ale cel udało się osiągnąć. Z przyjemnością zatem informuję, że aplikacja Portfela Emerytalnego jest już dostępna online pod adresami:
https://thorin87.github.io/ oraz
https://thorin87.github.io/retirement-savings/

Główne wyzwania jakie stanęły na drodze, to wydajne zapytanie do bazy o dane na potrzeby wykresu oraz problemy ze zbudowaniem wersji produkcyjnej frontendu.
Zapytanie do bazy niestety ciągle pozostawia wiele do życzenia (czas wykonania ~3s), ale zwraca dokładnie to czego potrzebuję. Przyjdzie jeszcze czas na jego optymalizację, na razie zostaje tak jak jest. Do tego drugiego problemu szczególnie przyłożył się moduł angular2-highcharts i błąd
Error encountered resolving symbol values statically. Calling function 'ChartModule', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function
wywołany przez poniższą linię w module aplikacji
    ChartModule.forRoot(require('highcharts/highstock'))
Jak rozwiązać ten problem? Odsyłam do mojego kodu na GitHub lub do oficjalnego issue założonego dla tego problemu.

Pozostałe zmiany we frontendzie to:
  1. wyłączenie Routingu (na razie go nie potrzebuję, cała aplikacja jest single page)
  2. wydzielenie adresu API do plików konfiguracyjnych (projekt wygenerowany z angular-cli od ręki obsługuje oddzielne pliki konfiguracyjne dla środowiska deweloperskiego i produkcji)
  3. wydzielenie modułu dla kart z podsumowaniem wyświetlanych na początku strony
  4. pobieranie i wyświetlanie danych z API (karty podsumowania, wykres i portfele)
  5. sporo drobnych poprawek i usuwania niepotrzebnych fragmentów kodu
Baza również przeszła drobną zmianę, ponieważ zupełnie bez sensu było trzymanie dat operacji kupna i sprzedaży zasobu (asset) w jednym wierszu. Teraz jest jedna data OperationDate i ewentualnie ilość jest mniejsza od zera, jeśli jest to sprzedaż.

W API też sporo zmian, ale bez rewolucji. Głównie są to poprawione lub rozszerzone już istniejące zapytania do bazy. Pojawiły się też 2 nowe metody - pobieranie danych do wykresu i podsumowania - ale opierają się o ten sam schemat, czyli wywołaj zapytanie i zwróć jego wynik jako JSON bez większej obróbki.

Jeszcze w tym tygodniu pojawi się podsumowanie całego miesiąca pracy i jej efektów, a także plan na ostatni już miesiąc konkursu. Zapraszam też do śledzenia mnie na Twitterze, gdzie pojawia się info o każdym nowym wpisie na blogu.

27 kwi 2017

Hosting aplikacji Angular w Github Pages

Dziś o tym, jak można za darmo opublikować stronę napisaną w Angular (a tak naprawdę każdą statyczną stronę) przy użyciu infrastruktury GitHub. Tytułowe GitHub Pages to po prostu kolejne repozytorium gita, które zakładamy w serwisie, a jego zawartość jest prezentowana jako strona w domenie github.io.

24 kwi 2017

Raport z placu boju - 8 tydzień konkursu Daj Się Poznać

Mija kolejny tydzień konkursu Daj Się Poznać, pora zatem na raport co się dzieje z aplikacją Portfela Emerytalnego. Poprzedni raport wypadał prawie dokładnie w środku kwietnia i po jego napisaniu zostały 2 tygodnie miesiąca, sprawdziłem więc jak idzie realizacja listy moich planów na ten miesiąc. Wniosek był prosty - niestety nie dam rady zrobić wszystkiego co zaplanowałem. Więcej o tym będzie w podsumowaniu całego miesiąca, ale w tym tygodniu pozwoliło mi to podjąć decyzję, że na razie skupiam się tylko na odczycie danych.

Aplikacja w trybie read-only będzie prezentowała to co ma zapisane w bazie, ale bez możliwości zmiany czy dodania kolejnych informacji. Skoro zatem zrezygnowałem na razie m.in. z możliwości dodawania portfeli i operacji w portfelach, to musiałem dodać je ręcznie bezpośrednio w bazie danych. Spisanie kilku moich zakupów z systemów transakcyjnych TFI nie było większym problemem, ale myślę, że kiedyś będzie musiała się pojawić opcja importu danych. Dodawanie kilkudziesięciu operacji nawet przez najwygodniejszy interfejs może skutecznie zniechęcić do użycia Portfela Emerytalnego.
Oprócz uzupełnienia stanu portfela dodałem też wszystkie fundusze prowadzone przez moich dostawców IKE i IKZE oraz kursy funduszy, które posiadam lub posiadałem. Dzięki temu baza jest już gotowa do policzenia wartości wszystkich moich funduszy w czasie.

Utworzyłem też strukturę, która będzie przechowywała dane o dostawcach produktów emerytalnych oraz samych produktach które oferują. Strukturę tworzą 3 tabele:
  1. FinancialInstitutionType - rodzaj instytucji finansowej, na początek są to
    • Towarzystwa funduszy inwestycyjnych (TFI)
    • Powszechne towarzystwa emerytalne (PTE)
    CREATE TABLE `FinancialInstitutionType` (
      `Id` int(11) NOT NULL AUTO_INCREMENT,
      `Code` varchar(10) NOT NULL,
      `Name` varchar(250) NOT NULL,
      PRIMARY KEY (`Id`)
    )
  2. FinancialInstitution - instytucje finansowe prowadzące IKE lub IKZE, przykładowo NN Investment Partners TFI S.A. lub PTE PZU SA
    CREATE TABLE `FinancialInstitution` (
      `Id` int(11) NOT NULL AUTO_INCREMENT,
      `Name` varchar(250) NOT NULL,
      `TypeId` int(11) NOT NULL,
      PRIMARY KEY (`Id`)
    )
  3. InvestmentProduct - w tej tabeli znajdą się konkretne produkty IKE i IKZE, które można założyć. Przykładowo będzie to IKE Plus prowadzone przez wymienione wcześniej NN TFI
    CREATE TABLE `InvestmentProduct` (
      `Id` int(11) NOT NULL AUTO_INCREMENT,
      `Name` varchar(250) NOT NULL,
      `Type` varchar(10) DEFAULT NULL,
      `FinancialInstitutionId` int(11) NOT NULL,
      PRIMARY KEY (`Id`)
    )
Poza dodanymi wierszami i nowymi tabelami pojawiło się również kilka kosmetycznych zmian. Są to np. zmiana pierwszych liter w nazwach tabel na duże i dodanie w tabeli Fund do jakiego InvestmentProduct należy. Tabela Wallet również dostała pole InvestmentProductId, ale tutaj będzie ono mogło być NULLem - do portfela można będzie dodać też np. gotówkę, która nie jest związana z żadnym produktem inwestycyjnym.

Mam nadzieję, że to koniec zmian i uzupełniania bazy, bo pora w końcu zabrać się za wyświetlanie tych wszystkich danych w interfejsie użytkownika - i to jest plan na najbliższy tydzień.

20 kwi 2017

Jakie jest najlepsze IDE dla Angular i dlaczego moim zdaniem jest to WebStorm

Chyba każdy programista lubi i potrzebuje dobrego środowiska programistycznego. Oczywiście pisać kod można nawet w notatniku i też będzie działało, ale zdecydowanie nie jest to produktywna droga. Dziś będę chwalił oprogramowanie ze stajni JetBrains - tytułowy WebStorm, który zdecydowanie wspomaga pracę i zwiększa tempo rozwoju aplikacji.

17 kwi 2017

Raport z placu boju - 7 tydzień DSP

Upłynął kolejny tydzień, więc pora na raport co z moim projektem konkursowym.

Ostatnio pisałem, że nie mogę dodać operacji w API które modyfikują bazę, dopóki nie będę mógł w jakiś sposób uwierzytelniać i autoryzować użytkowników. Naturalnie otwierałoby to możliwość zmian każdemu użytkownikowi w każdym portfelu. Nie chciałem pisać całego modułu użytkowników, logowanie przez Facebook czy innego dostawcę też wydawało się czasochłonne jak na potrzeby prostego demo do którego dążę. Zdecydowałem się na tymczasowe rozwiązanie w postaci tokenów. Założenie tego rozwiązania są następujące:
  • użytkownik odwiedza stronę bez tokena - dostaje informację o projekcie, być może wyświetla mu się przykładowy portfel
  • użytkownik bez tokena robi akcję na stronie (np. założenie swojego portfela) - jest generowany dla niego token, który zostaje dopisany do adresu url strony
  • użytkownik odwiedza stronę z tokenem w url - widzi swój portfel
System jest prosty (można by nawet powiedzieć, że prostacki), ale spełni swoje zadanie na ten moment. Jest otwarty na udoskonalenia (np. token można zapisać w cookie zamiast url), po dodaniu innego systemu uwierzytelnienia można go łatwo zintegrować z nowym rozwiązaniem. No i najważniejsza jego zaleta - mieści się w kilku liniach kodu
@app.route("/token", methods=['GET', 'POST'])
def token():
    if request.method == 'POST' and 'token' in request.json:
        query = "INSERT INTO user (Token, Admin) VALUES ('{0}', 0)"
        query = query.format(request.json['token'])
        try:
            insertedId = insertToDb(query)
            return jsonify(userid=insertedId, error=None)
        except:
            error = "Error: unable to insert token"
            return jsonify(userid=None, error=error)
    else:
        return jsonify(token=uuid.uuid4())
        
def insertToDb(query):
    cursor = mysql.connection.cursor()
    cursor.execute(query)
    mysql.connection.commit()
    return cursor.lastrowid

Drugą zmianą z ubiegłego tygodnia jest pojawienie się serwisu, który ma automatycznie pobierać i zapisywać kursy funduszy inwestycyjnych. Tydzień temu wspomniałem, że udało mi się znaleźć na stronie TFI Nationale-Nederlanden adres pod jakim są dostępne pliki json z potrzebnymi mi danymi. Dodany przeze mnie do projektu DataDownloader wykorzystuje te właśnie adresy i dla trzech przykładowych funduszy pobiera i zapisuje pliki z wartościami funduszy w czasie. Do zrobienia pozostaje interpretacja tych danych i wysłanie ich do zapisu do API, a kolejne kroki to dodanie pobierania dla innych TFI. Nie wiem jednak od jakich zacząć, więc daj proszę znać w komentarzu pod tym postem na jakich funduszach by Ci zależało.

14 kwi 2017

Jak oszczędzać na emeryturę?

Kolejny raz opóźnia się mój założony cykl wydawniczy i znowu publikuję z jednodniowym poślizgiem. Nie wiem czy są tu jacyś czytelnicy, którzy co poniedziałek i czwartek ze zniecierpliwieniem odświeżają stronę w oczekiwaniu na posta - jeśli są to przepraszam za tę sytuację. Postaram się poprawić :) Do rzeczy jednak. Dziś chciałbym poruszyć temat rzekę - czyli jak oszczędzać na emeryturę.

Ale zanim o tym jak oszczędzać, to najpierw odpowiem na pytanie czy oszczędzać i dlaczego. Jeśli czytasz ten artykuł to prawdopodobnie wiesz już, że oszczędzać na emeryturę należy. W mediach zaczęło się o tym mówić, pojawiają się reklamy o młodych bogach itd. Wydaje mi się, że obecni 20-30-40 latkowie mają świadomość tego, jak będą wyglądały ich emerytury z ZUS - szczególnie w kontekście ostatniego obniżenia wieku emerytalnego. Jeśli jednak ktoś ma jeszcze jakieś wątpliwości, to polecam uważne przyjrzenie się poniższemu wykresowi
Źródło: http://grape.org.pl/blog/co-dokladnie-oznacza-obnizanie-wieku-emerytalnego-w-polsce/

Jeśli zatem masz 20-30 lat, to masz około 70% szans na to, że twoja emerytura od państwa będzie minimalna. Na tę chwilę jest to chyba 880zł, od 1 października 1000zł. Co prawda co roku coś się zmienia w systemie emerytalnym, ale myślę że najbezpieczniej jest założyć, że większość emerytury (jeśli nie całość) musimy sobie zapewnić samemu.

Powróćmy jednak do głównego wątku. Tytułowe pytanie usłyszałem ostatnio od jednej ze znajomych i w pierwszej chwili nie wiedziałem co odpowiedzieć. Jest tyle możliwości, że mógłbym opowiadać o tym przez kilka godzin. Jak streścić te wszystkie opcje tak, żeby nie przytłoczyć i nie zniechęcić? Czy zagłębiać się w inwestowanie na giełdzie albo w kupno funduszy inwestycyjnych? Dużo przecież zależy też od profilu danej osoby i tego, ile czasu chce poświęcić na zarządzanie swoimi oszczędnościami.

Najlepszą odpowiedzią jaka mi przyszła do głowy jest: przede wszystkim oszczędzaj. Odkładaj co miesiąc stałą kwotę, najlepiej około 10% swoich dochodów na oddzielne konto. Nie możesz odkładać aż tyle? Odłóż najpierw 100 zł miesięcznie i w miarę możliwości (np. po otrzymaniu podwyżki wynagrodzenia) zwiększaj tę kwotę. Utwórz zlecenie stałe, które zaraz po wypłacie przeleje pieniądze na ten cel - jeśli zostaną odłożone już wtedy, to na pewno ich nie wydasz. Ważna jest przede wszystkim systematyczność. Jeśli osiągniesz ten krok, to dopiero wtedy możesz przejść dalej.

Drugą ważną rzeczą jest korzystne oprocentowanie Twoich środków na emeryturę. Magia procentu składanego naprawdę działa. Na początku (przynajmniej mi) wydawało się, że oszczędności przyrastają powoli - trzeba jednak pozwolić im pracować, a przez kilkadziesiąt lat odsetki od zgromadzonej kwoty prawdopodobnie przekroczą wpłacony kapitał. Dla przykładu wezmę opcję minimum z poprzedniego punktu (czyli 100 zł). Na poniższych wykresach widać, jak zachowuje się zaoszczędzona kwota kiedy odkładamy ją regularnie przez 30 lat. Pokazuję dwa warianty - rachunek oprocentowany na 3% i 5% rocznie z naliczaniem odsetek co miesiąc.
Jak na dłoni widać, jak dużą różnicę robi każdy punkt procentowy więcej w kwestii ostatecznej kwoty jaką otrzymamy. Celowo pominąłem na powyższych obliczeniach podatek Belki, czyli 19% podatku od zysku. Pominąłem go dlatego, żeby teraz pokazać jak zachowa się zaoszczędzona kwota kiedy ten podatek uwzględnię
W tym wariancie jest to ponad 13000 zł różnicy pomiędzy tymi dwiema opcjami i to odkładając jedyne 100 zł miesięcznie. Piszę o tym dlatego, bo chcę pokazać wymierne korzyści z posiadania konta IKE lub IKZE, które są zwolnione z podatku od zysków kapitałowych. Nawet odkładając niewielkie kwoty z myślą o zabezpieczeniu emerytury warto założyć jedno z tych kont. Jest to najłatwiejsza metoda na korzystniejsze efektywne oprocentowanie i poprawienie ostatecznego wyniku jaki osiągniesz. Najprostszą wersją takiego konta (bezpieczną i nie zajmującą czasu) będzie lokata bankowa pod "parasolem" IKE. Najlepsze warunki takiego IKE ma obecnie bank Millenium, który oferuje 3% na lokacie z kapitalizacją roczną.

Opisałem dwa punkty na drodze do spokojnej emerytury, o które moim zdaniem każdy powinien zadbać. To jednak nie koniec, bo sposobów na poprawienie ostatecznego wyniku jest więcej. Ja nie zamierzam zadowolić się maksymalnie 3% które płacą banki na IKE w postaci lokaty. W kolejnej części opiszę, jak można próbować wyciągnąć więcej i jak może się do tego przydać Portfel Emerytalny który piszę.

11 kwi 2017

Raport z placu boju - 6 tydzień DSP

Dzisiejszy raport wyjątkowo pojawia się we wtorek, czyli dzień później niż wynikałoby to z mojego planu i wcześniejszych zapowiedzi. W ubiegłym tygodniu sprawy prywatne zajęły mi cały dostępny czas i niestety nie udało mi się nic zrobić w projekcie. Nie chciałem wrzucać wpisu tylko po to, żeby opisać w nim, że nic nie zrobiłem - dlatego właśnie postanowiłem odłożyć posta na dzień później, a w międzyczasie postarać się o materiał na niego. Właśnie z tego względu nie mam dziś do opisania zbyt wiele, ale lepsze to niż nic :)

W projekcie pojawiły się nowe tabele w bazie danych: wallet i asset . Będą one służyły do przechowywania odpowiednio:
  • portfeli, czyli zbioru inwestycji danego użytkownika. W portfelach na razie będą mogły być tylko jednostki funduszy inwestycyjnych, ale docelowo również akcje, obligacje, gotówka itp.
  • pojedynczych składników z których jest zbudowany portfel. W tej tabeli znajdą się posiadane ilości jednostek funduszy oraz daty ich zakupu i ewentualnej sprzedaży. Zawartość tej tabeli można także rozumieć jako operacje wykonywane w portfelach
Zostały również dodane nowe metody w API, które także dotyczą portfela i operacji na nim. Można więc za pomocą API pobrać listę aktualnie posiadanych walorów i historię operacji. Musiałem dopisać też kilka pomocniczych metod jak np. pobranie listy dostępnych funduszy. Dodałem również możliwość wysłania do API informacji o kupnie i sprzedaży jednostek funduszy. Tu jednak musiałem się zatrzymać, bo zanim będę mógł dodawać kolejne operacje, które można wykonać, to muszę przemyśleć jak będzie wyglądała autentykacja i autoryzacja użytkowników.

Ostatnią rzeczą na którą poświęciłem kilka chwil to badanie możliwości automatycznego pobierania kursów funduszy. Każde towarzystwo funduszy inwestycyjnych ma obowiązek publikowania wyników prowadzonych przez siebie inwestycji, więc te dane są publicznie dostępne. Problemem pozostaje ich pobranie, bo prawdopodobnie będzie trzeba pisać dedykowaną metodę dla każdego TFI. Rozważałem również użycie narzędzi do testowania interfejsów użytkownika (jak np. Selenium), któremu mógłbym wskazać jaką stronę ma otworzyć, jaki przycisk kliknąć i gdzie zapisać wygenerowany plik. Zbadałem jak to wygląda w przypadku NN TFI i udało mi się wyłuskać z kodu linki pod jakimi są dostępne notowania konkretnych funduszy. Otwiera to drogę do jakiegoś prostego pobieracza tych plików, ale to już temat na kolejne tygodnie.

6 kwi 2017

4developers 2017 z mojej perspektywy

W ostatni poniedziałek miałem przyjemność uczestniczyć w interdyscyplinarnym festiwalu technologicznym 4developers, czyli jednej z największych konferencji dla programistów w Polsce. Dziś, kilka dni po tym wydarzeniu, chciałbym podzielić się moimi spostrzeżeniami i przemyśleniami na jego temat.

Konferencja odbyła się w Warszawie w hotelu Sangate Airport. Na 3 piętrach części konferencyjnej można było uczestniczyć w aż 14 ścieżkach tematycznych, dodatkowo dla uczestników została przygotowana strefa relaksu z pufami i rozrywkami w stylu ping-ponga czy konsoli. Ogólnie sporo miejsca, ale uczestników też było mnóstwo. Organizatorzy mówią o 1800 osobach, co zdecydowanie dało się odczuć. Momentami było po prostu odrobinę tłoczno, szczególnie na klatkach schodowych. Poza tą drobną niedogodnością obiekt gdzie odbywała się konferencja był bardzo dobrze przygotowany - duży plus dla organizatorów.

Co do samego przebiegu wydarzenia, to ja spędziłem go bardzo aktywnie. Ilość dostępnych ścieżek wręcz przytłaczała i niejednokrotnie stawałem przed trudną decyzją, który wykład wybrać spośród kilku opcji. Liczę na to, że pojawią się nagrania tych, które musiałem odrzucić i będę mógł nadrobić niemożliwość rozdwojenia się :) 15 minut przerwy pomiędzy kolejnymi pozycjami agendy jest w sam raz żeby wypić kawę i zmienić salę, ale jeśli czytasz to przed kolejną edycją to lepiej zaplanuj co chcesz zobaczyć już dzień wcześniej.

Jeśli chodzi o prelekcje, to te na które trafiłem merytorycznie były bardzo dobrze przygotowane. Jedyny minus - zdarzyło się, że musiałem siedzieć na podłodze, bo zabrakło miejsc. Nie mogę tu jednak nikogo winić za taki stan rzeczy, pewnie gdybym wcześniej na nie przychodził to nie byłoby tego problemu ;)

Co udało mi się wynieść z konferencji i na co warto zwrócić uwagę

  • Konrad Kokosa opowiedział o ETW, czyli mechanizmie Event Tracing for Windows. Świetne rozwiązanie do śledzenia co dzieje się z naszą aplikacją i jak współpracuje ona z systemem. Ma bardzo niewielki narzut, co pozwala stosować go nawet w środowisku produkcyjnym. Wygląda na niezwykle pomocne w szukaniu skomplikowanych błędów.
  • .NET Core - Microsoft dwoi i się i troi żeby udostępnić jedno środowisko dla wszystkich platform i idzie mu coraz lepiej. Łukasz Pyrzyk zgrabnie podsumował w jakim stanie aktualnie znajduje się .NET Core i powiedział o nowych funkcjach jak Span<T>, ArrayPool czy ValueTask. Rewolucji może nie będzie, ale ewoluuje w zdecydowanie dobrym kierunku.
  • Serverless - na ten temat był nawet więcej niż jeden wykład, ja byłem na tym gdzie prezentował Jakub Gutowski (znany jako Gutek). Serverless zmienia podejście do pojęcia serwera, niejako zwalnia z myślenia o nim. Można to określić jako nanoserwisy - wrzucamy na serwer wręcz pojedyncze funkcje które wywołujemy jak usługi. Skalowaniem rozwiązania zajmuje się dostawca, płatność jest za ilość wywołań. Ciekawy trend który warto kojarzyć.
  • GraphQL - jedna z ostatnich nowości w tworzeniu elastycznych API. Pozwala korzystającemu z naszej usługi na zdecydowanie, jak szeroki zakres danych chce otrzymać w odpowiedzi. Powinno zainteresować każdego, kto buduje API dla wielu klientów i każdy z nich potrzebuje innego zestawu danych w odpowiedzi na to samo zapytanie. Prezentował Piotr Gankiewicz - zwycięzca Daj Się Poznać 2016.
  • Porty i adaptery - architektura wręcz niezbędna dla każdej większej aplikacji biznesowej, znam i korzystam, ale Dominik Przybysz pomógł mi swoim wykładem nieco lepiej usystematyzować wiedzę.
Podsumowując - czy warto kupić wejściówkę? Moim zdaniem warto, bo konferencja jest solidnie zorganizowana, nie ma żadnego pitu-pitu tylko zastrzyk naprawdę solidnej wiedzy. Pro-tip: warto przed zakupem poszukać kodu rabatowego, można kupić bilet 15-20% taniej. Mam zatem nadzieję, że widzimy się na kolejnej edycji!

3 kwi 2017

Raport z placu boju - 5 tydzień DSP

Cześć! Tym wpisem rozpoczynam cotygodniową serię raportów z tworzenia Portfela Emerytalnego. Tak jak pisałem w ostatnim poście teraz takie podsumowania będą pojawiać się raz na tydzień w poniedziałki i będą zawierać podsumowania co udało się zrobić w ostatnim czasie w moim projekcie na konkurs Daj Się Poznać 2017.

Szablon strony

W ostatnim tygodniu znalazłem gotowy, darmowy szablon strony na podstawie którego będę budował interfejs użytkownika. Zależało mi na tym, aby mieć jak najmniej pracy związanej z  dostosowywaniem szablonu do moich potrzeb, dlatego od razu szukałem takiego, który będzie przystosowany do Angular 2. Ważne było też, żeby działał zarówno na dużych ekranach komputerów, jak i na smartfonach. Ten który znalazłem jest responsywny, zbudowany na bootstrap i wykorzystuje Material Design od Google. Material Design daje jeszcze jedną, istotną zaletę - zbiór gotowych komponentów do wykorzystania: https://material.angular.io/.
Nie może być jednak idealnie i szablon miesza trochę czystego JavaScript z TypeScriptem, ale mam nadzieję to uporządkować w trakcie rozwoju aplikacji.

Twórca zrobił tutaj kawał dobrej roboty, więc w podziękowaniu link do strony: https://www.creative-tim.com/product/material-dashboard-angular2

Dostosowanie szablonu

Pobrany szablon musiałem jeszcze zintegrować z wygenerowaną z angular-cli aplikacją i na jego podstawie zbudować zalążek tego, jak będzie się prezentował interfejs użytkownika Portfela Emerytalnego. W tej kwestii czeka mnie jeszcze sporo pracy, ale pierwsze rezultaty prezentują się następująco:

Zmiana biblioteki do wyświetlania wykresów

Ostatnią zmianą wprowadzoną w ubiegłym tygodniu jest rezygnacja z ng2-charts, którego pierwotnie chciałem użyć do wyświetlania wykresów. Podjąłem wiele prób wyświetlania danych przy użyciu tej biblioteki, rozwiązałem wiele pojawiających się problemów, ale wykresy nadal nie działały tak jak oczekiwałem. Przykładem niech będzie to, że kiedy zmieniałem ilość punktów które ma wyświetlić wykres to ten rzucał błędem parsowania.
Żeby nie zamieniać programowania w hackowanie tej biblioteki żeby działała, postanowiłem spróbować innego rozwiązania. Wybrałem angular2-highcharts, który okazał się idealnym rozwiązaniem wolnym od problemów z którymi zetknąłem się używając ng2-charts. Dodatkowo highchart od ręki obsługuje wykresy, na których możemy wybrać zakres czasu dla jakiego zostaną pokazane dane.
Kolejna rzecz mniej do napisania samemu, co ostatecznie zadecydowało o wyborze tego rozwiązania.

To tyle jeśli chodzi o dzisiejszego, opóźnionego posta. Na kolejne podsumowanie zapraszam za tydzień.

30 mar 2017

Podsumowanie pierwszego miesiąca DSP i plany dalszego działania

Kończy się marzec, a wraz z nim pierwszy miesiąc trwania konkursu Daj Się Poznać. Portfel Emerytalny, czyli mój projekt konkursowy, naturalnie również jest rozwijany już miesiąc. Co przez ten czas udało się zrobić, a gdzie zawaliłem sprawę? Jakie mam plany na kwiecień i jakie zmiany czekają bloga? O tym wszystkim w dzisiejszym wpisie.

27 mar 2017

Połączenie backendu z frontendem, czyli odbieranie danych z API w Angular

W dzisiejszym poście zamierzam pokazać jak odebrać dane z API w Angular i wyświetlić je w aplikacji - czyli ciąg dalszy spinania aplikacji w całość. Na razie wyświetlę tylko suche dane, bez "ubierania" ich w wykres - na ten temat pojawi się osobny post.

23 mar 2017

Python Flask i MySQL - łatwo i szybko czy droga przez mękę?

Kontynuując post z poniedziałku pozostaję w temacie połączenia Flask i MySQL. W dzisiejszym wpisie będzie case study jak to połączenie odbyło się w moim projekcie - w końcu pora zacząć spinać wszystkie elementy w jedną, działającą całość.

W poprzednim wpisie podałem kilka modułów do MySQL dostępnych dla Flask, ale nie wspomniałem którego użyję. Pierwsza wersja backendu używała Flask-MySQL, zdecydowałem jednak o zmianie na Flask-MySQLdb. Różnica niewielka, ale przekonała mnie kompatybilność z Python 3+. Niestety po wydaniu polecenia
pip install flask-mysqldb
zobaczyłem jedynie błąd
running build_ext
building '_mysql' extension
error: Microsoft Visual C++ 9.0 is required. Get it from http://aka.ms/vcpython27
pobranie Microsoft Visual C++ Compiler for Python 2.7 i uruchomienie instalacji zmieniło tylko komunikat na
_mysql.c(29) : fatal error C1083: Cannot open include file: 'my_config.h': No such file or directory
Na szczęście jest stackoverflow, zgodnie ze znalezioną poradą pobrałem odpowiednią paczkę ze strony http://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient (w moim przypadku mysqlclient-1.3.10-cp27-cp27m-win32.whl), kilka poleceń w konsoli
pip install wheel
Successfully installed wheel-0.29.0

pip install .\mysqlclient-1.3.10-cp27-cp27m-win32.whl
Successfully installed mysqlclient-1.3.10

pip install flask-mysqldb
Installing collected packages: flask-mysqldb
Successfully installed flask-mysqldb-0.2.0
Zatem w końcu sukces, a to dopiero początek drogi.

Jak wczytać ustawienia z zewnętrznego pliku
Niezależnie jednak od użytego modułu pojawiła się potrzeba zapisania danych połączenia z bazą w osobnym pliku. Można to zrobić na wiele sposobów, np.
  • plik z kodem Python, który importuje się jak inne moduły
  • JSON
  • YAML, czyli specjalny format do przechowywania konfiguracji
  • plik INI
  • standardowy XML
Bardzo dobre zestawienie tych metod razem z przykładami użycia jest dostępne tutaj.
Najłatwiejsza i wystarczająca w moim przypadku wydaje się metoda nr 1 i tak powstał plik databaseconfig.py:
mysql = {'host': 'database_host',
         'user': 'database_user',
         'passwd': 'database_passwd',
         'db': 'database_name'}
Kod!
Pora na programistyczne mięcho. Mam już wszystko żeby napisać kolejną metodę do API,  postanowiłem więc przygotować dane do wyświetlenia na wykresie w interfejsie użytkownika.
Dodaję import flask_mysqldb oraz jsonify z modułu flask (tworzy obiekt response z jsonem który można zwrócić bezpośrednio z metody), wczytuję konfigurację z pliku. Nagłówek pliku app.py z wygląda teraz tak:
from flask import Flask
from flask import Response
from flask import jsonify
from flask_mysqldb import MySQL

app = Flask(__name__)

import databaseconfig as cfg
app.config['MYSQL_USER'] = cfg.mysql['user']
app.config['MYSQL_PASSWORD'] = cfg.mysql['passwd']
app.config['MYSQL_DB'] = cfg.mysql['db']
app.config['MYSQL_HOST'] = cfg.mysql['host']
mysql = MySQL(app)
a metoda pobierająca dane z bazy tak:
@app.route("/dbtest")
def fetchfromdb():
    query_string = "SELECT Date, Value FROM rate WHERE Date > '2015-01-01' AND FundId = 1" 
    cursor = mysql.connection.cursor()
    cursor.execute(query_string)
    return jsonify(data=cursor.fetchall())
Sukces? Jeszcze nie. Niestety przygotowana przeze mnie metoda po wywołaniu wyrzuciła błąd z parsowaniem typu decimal
TypeError: Decimal('110.11') is not JSON serializable
Parsowanie decimal
O co chodzi z tym błędem? Otóż JSON w swojej specyfikacji nie uwzględnia takiego typu jak decimal, więc autorzy Flask nie implementowali swojej wersji tego jak ma być serializowany. Chcesz mieć decimal - musisz sam zdecydować jak ma on być zapisywany. Można oczywiście pozbyć się decimali z zapytania do bazy
SELECT Date, CAST(Value * 100 AS INT) FROM rate WHERE Date > '2015-01-01' AND FundId = 1
ale to tylko obejście problemu zamiast jego rozwiązania.
Na szczęście domyślny parser JSON można nadpisać swoją implementacją, w której zdefiniujemy zachowanie dla wybranych typów, a reszta zostanie w domyślnej postaci:
import flask.json
import decimal

class MyJSONEncoder(flask.json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, decimal.Decimal):
            # Convert decimal instances to strings.
            return str(obj)
        return super(MyJSONEncoder, self).default(obj)
app.json_encoder = MyJSONEncoder
Po takiej zmianie aplikacja działa już poprawnie i zwraca dane jakie możemy odebrać we frontendzie.

Po rozwiązaniu powyższego problemu dowiedziałem się jeszcze o bibliotece simplejson, która zawiera domyślną metodę obsługi decimal. Chciałem jednak pozostać przy Flask.jsonify że względu na to, że zwraca od razu obiekt Response gotowy do zwrócenia z funkcji. Nie testowałem, ale ponoć
If you install the simplejson package, flask.jsonify will automatically use that instead of the stdlib json library.
Na koniec odniosę się do pytania, które umieściłem w tytule. Niestety nie mogę powiedzieć żeby połączenie z MySQL było wybitnie łatwe - w całym procesie pojawiło się kilka problemów. Część z nich wynika na pewno z mojej nieznajomości Pythona. Na szczeście nie była to również droga przez mękę i nadal uważam że Flask był dobrym wyborem jeśli chodzi o szybkie prototypowanie backendu. Zobaczymy czy i jak długo ta opinia się utrzyma :)

20 mar 2017

Przegląd dostępnych rozwiązań do połączenia Flask i MySQL

Ten post jest pierwszą częścią opisu współpracy Flask i MySQL. Kiedy zacząłem tworzyć wpis dotyczący połączenia bazy i backendu w moim projekcie, to chciałem w nim opisać kompleksowo wszystko czego się nauczyłem w trakcie poznawania Flask. Post rozrósł się do ogromnego wypracowania, dlatego został podzielony na części. Dzisiaj opiszę dostępne metody takiego połączenia, na pewno pojawi się również opis konkretnego wdrożenia na przykładzie Portfela Emerytalnego. Być może na tym się nie skończy, bo temat jest naprawdę obszerny.

Poszukiwania metody połączenia się z bazą przyniosły odkrycie, że istnieje kilka modułów których możemy użyć w tym celu. Znalezione przeze mnie to:
Wymieniłem tylko takie związane wprost z Flask, bo dla samego Pythona istnieje ich wiele więcej (MySQLdb, mysqlclient, Connector/Python, SQLObject, peewee, PonyORM itd.). Taki wybór w założeniu ma zapewnić brak problemów w użyciu w połączeniu z Flask.
Krótki opis każdego z modułów (forma jest celowo dość ścisła, post ma być szybką ściągawką dla mnie i być innych szukających tego typu zestawienia).

Flask-MySQL

Strona projektu: https://flask-mysql.readthedocs.io
Chyba najprostszy z wymienionych modułów, oparty na wymienionym powyżej MySQLdb. Niestety z tego powodu działa tylko z Python w wersji 2.4-2.7. Dla mnie nie jest to problem, ale jeśli ktoś pisze w Python 3+ to nie skorzysta z tego rozszerzenia. Ciągle dość popularny i dobrze wypozycjonowany, ja jednak nie będę go używał.

Inicjalizacja:
from flask import Flask
from flaskext.mysql import MySQL

app = Flask(__name__)
mysql = MySQL()
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
app.config['MYSQL_DATABASE_USER'] = 'db_username'
app.config['MYSQL_DATABASE_PASSWORD'] = 'db_password'
app.config['MYSQL_DATABASE_DB'] = 'db_name'
mysql.init_app(app)
Użycie:
connection = mysql.connect()
cursor = connection.cursor()
cursor.execute("SELECT * FROM user")
data = cursor.fetchall()

Flask-MySQLdb

Strona projektu: http://flask-mysqldb.readthedocs.io
W skrócie i uproszczeniu: ulepszona wersja poprzedniego modułu, obsługuje Python 3. Zacytuję wypowiedź autora którą znalazłem:
I wrote it because back then flask-mysql didn't work outside of a request context (not sure if it does now) and because it's based on MySQL-python while flask-mysqldb is based on mysqlclient which is fully backwards compatible fork of MySQL-python and is compatible with Python 3.3+. You mentioned you're using Python 3.4.3 so flask-mysql will not work.
flask-mysqldb is really meant to be a tiny, tiny wrapper for mysqlclient so if you need something more like an ORM flask-sqlalchemy is definitely the way to go.
Inicjalizacja:
from flask import Flask
from flask_mysqldb import MySQL

app = Flask(__name__)
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'db_username'
app.config['MYSQL_PASSWORD'] = 'db_password'
app.config['MYSQL_DB'] = 'db_name'
mysql = MySQL(app)
Użycie:
cursor = mysql.connection.cursor()
cursor.execute("SELECT * FROM user")
data = cursor.fetchall()

Flask-SQLAlchemy

Strona projektu: http://flask-sqlalchemy.pocoo.org/2.1/
Bardziej ORM niż prosty moduł do połączenia z bazą. Najpopularniejszy wśród Pythonowych ORMów, prawdopodobnie dlatego dorobił się dedykowanego modułu dla Flask.

Inicjalizacja:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@localhost/db_name'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, username, email):
        self.username = username
        self.email = email

    def __repr__(self):
        return '' % self.username
Użycie:
data = User.query.all()

16 mar 2017

Baza danych: struktura, przykładowe dane i połączenie

W ostatnim poście napisałem, że kolejnym krokiem będzie odbieranie we frontendzie przykładowych danych z api. Życie jednak zweryfikowało te plany i trafiłem na jakiś błąd parsowania json przez przeglądarkę w momencie odbierania żądania. Nie mogłem się go pozbyć pomimo wielu prób, stwierdziłem zatem, że szkoda na to czasu. Lepiej sprawdzić czy ten błąd występuje również kiedy odbiorę dane z bazy i te dane zserializuję do json. Jeśli będzie ten sam błąd - to wtedy poszukam co jest nie tak, a jest szansa że problem w ogóle się nie pojawi.W związku z powyższym w dzisiejszym poście opiszę przygotowanie bazy danych.

Swoją bazę stawiam w hekko.pl, mam u nich wykupiony hosting więc przy okazji użyję go do tego projektu. Samo wygenerowanie bazy odbywa się przez panel DirectAdmin i sprowadza się do kilku kliknięć, więc nie ma tu zbyt wiele do opisania. Jest dostępny phpMyAdmin do zarządzania bazą, ale mam trochę wstręt do niego i od razu pobrałem MySQL Workbench. Przy pierwszej próbie połączenia okazało się, że muszę jeszcze wprost ustawić jakie hosty mają dostęp do bazy. Na czas testów dodałem %, czyli po prostu dostęp dla wszystkich

Struktura bazy na potrzeby pierwszej wersji portfela emerytalnego prezentuje się następująco:
Na potrzeby wyświetlenia we frontendzie przykładowego wykresu potrzebuję jedynie wartości funduszy w czasie, więc zakładam tylko tabele Fund (będzie zawierała nazwy funduszy) oraz Rate (wartość w czasie):
CREATE TABLE `fund` (
 `Id` int(11) NOT NULL AUTO_INCREMENT,
 `Name` varchar(256) NOT NULL,
 PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `rate` (
 `Id` int(11) NOT NULL AUTO_INCREMENT,
 `Date` date NOT NULL,
 `Value` decimal(10,2) NOT NULL,
 `LastUpdate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
 `FundId` int(11) NOT NULL,
 PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Pozostało jeszcze tylko uzupełnić tabelę przykładowymi danymi. Kursy funduszu pobieram ze strony TFI i parsuję przy pomocy narzędzia regexr - wyrażenia regularne spisują się znakomicie do takiego wyselekcjonowania danych
Wszystko łączę w zapytania i wykonuję na bazie:
INSERT INTO fund (`Name`) VALUES ('NN (L) Stabilny Globalnej Alokacji (K)')
INSERT INTO rate (`Date`, `Value`, `FundId`) VALUES
('2014-09-24', 106.66, 1),
('2014-09-25', 106.44, 1),
('2014-09-26', 106.83, 1),
('2014-09-29', 106.71, 1),
...
To tyle na dziś, kolejny post będzie o tym jak te dane z bazy odebrać w backendzie i wystawić je jako json. Zapowiada się długi wpis, bo ponownie pojawiło się kilka problemów - po szczegóły zapraszam w poniedziałek.

13 mar 2017

Pierwsze kroki z Python, Flask i Heroku

W trakcie pisania portfela emerytalnego chcę nauczyć się czegoś nowego, stąd pomysł na użycie języka Python. Po krótkich poszukiwaniach znalazłem też prosty framework do API, czyli Flask. Uruchomienie przykładu ze strony Flask na localhost poszło jeszcze szybciej niż postawienie szkieletu strony w Angular i sprowadza się do utworzenia jednego pliku i wywołania dwóch komend w konsoli. Nie chcę przepisywać treści z oficjalnej strony więc zainteresowanych odsyłam na http://flask.pocoo.org/

Wybierając Python jako język w którym powstanie backend miałem nadzieję (a nawet byłem przekonany), że będę mógł uruchomić napisane przeze mnie skrypty na hostingu który posiadam. O jakże naiwne było to podejście ;) Nawet jeśli udałoby się uruchomić jakiś prosty skrypt to nie było mowy o zainstalowaniu czegokolwiek - a ja potrzebowałem wspomniany wyżej Flask.
Na szczęście są platformy w chmurze w modelu PaaS (Platform as a Service, czyli dostajemy gotowe całe środowisko w którym uruchamiamy swoje aplikacje). Nigdy nie korzystałem z takich platform, więc znowu pojawiła się okazja do nauki nowych rzeczy. Po szybkim przeszukaniu sieci znalazłem Google App Engine (GAE) oraz Heroku. W obydwu tych miejscach można bez problemu można uruchomić prostą aplikację bez konieczności płacenia, a kiedy potrzebujemy większych zasobów to płacimy za ich zużycie.

Moje pierwsze kroki skierowałem w stronę GAE, ale ilość opcji i skomplikowanie instalacji szybko mnie zniechęciły. Heroku okazało się nie mieć żadnej z tych wad i po krótkiej konfiguracji udało się utworzyć aplikację retirement-savings-api i uruchomić jej pierwszą wersję - standardowe Hello World o którym pisałem we wstępie.
Pewnym zaskoczeniem dla mnie było to, jak uploaduje się aplikację na serwer. Działa to tak, że po stronie serwera mamy uruchomione repozytorium git - więc wystarczy
heroku git:remote -a retirement-savings-api
git add .
git commit -m "stub"
git push heroku master
i aplikacja już jest na serwerze gotowa do działania. Jeszcze słowem wyjaśnienia - komenda heroku wywoływana powyżej pochodzi z narzędzia udostępnionego przez Heroku, ale nic nie stoi na przeszkodzie żeby użyć po prostu
git remote add heroku https://git.heroku.com/retirement-savings-api.git
Zachęcony początkowymi sukcesami postanowiłem przygotować jakieś konkretne dane z których będzie mógł skorzystać frontend. Na początek dodałem statyczny plik z jsonem który API ma odczytywać i po prostu zwracać do klienta. Dopisałem krótką metodę:
@app.route("/test")
def testdata():
    file = open('static/testdata.json', 'r') 
    file_contents = file.read()
    resp = Response(file_contents, status=200, mimetype='application/json')
    return resp
Ponownie commit, push i sprawdzam https://retirement-savings-api.herokuapp.com/test. Wszystko działa jak należy, dane z pliku wyświetlają się, więc teraz pora odebrać te dane po stronie frontu - ale to już materiał na następnego posta.

9 mar 2017

Jak postawić stronę w Angular 2 w 5 minut

Pora w końcu napisać bardziej techniczny post. Na pierwszy ogień idzie frontend. Tak naprawdę samego kodu nie będzie zbyt wiele, bo dziś opiszę jak postawić działający szkielet witryny i uruchomić go lokalnie. Tytuł nie jest przesadzony i naprawdę można to zrobić w 5 minut, co zaraz się okaże.

6 mar 2017

Emerytalny Portfel Inwestycyjny - opis projektu

Zaczynamy tydzień kolejnym wpisem, dziś przekazuję więcej informacji na temat projektu, który realizuję w ramach konkursu Daj Się Poznać. Czym więc jest tytułowy Emerytalny Portfel Inwestycyjny? Krótko mówiąc - miejscem gdzie można śledzić postępy w oszczędzaniu na emeryturę, zobaczyć na wykresie jak przyrastają (lub, o zgrozo - topnieją) nasze inwestycje, dostać powiadomienie jeśli warto zamienić dane aktywa na inne oraz sprawdzić kiedy w takim tempie na tę emeryturę uzbieramy.

1 mar 2017

Hello World

Witaj na moim blogu! W pierwszym wpisie wypada się przedstawić, zatem kilka słów o mnie: tata, mąż i programista .NET z ponad 7 letnim stażem. Moim hobby są finanse (w każdym aspekcie) a w wolnym czasie nałogowo oglądam seriale.