Projekt 1

Opis projektu

Zadanie

Zadanie polega na zaproponowaniu implementacji klasy currency, która pozwala na pozyskiwania, proste zarządzanie oraz prostą wizualizację kursów średnich NBP. Poniżej jest dokładny opis wszystkich funkcjonalności takiej klasy. Moje przykładowe rozwiązanie opiera się o model R6 ale mogą Państwo wykorzystać dowolny model obiektowy.

Klasa currency musi pozwalać tworzyć obiekty w taki sposób, że w trakcie tworzenia nowego obiektu łączy się przez API z serwerami NBP i pozyskuje kursy średnie na zadanej waluty. Typowy przykład jest podane poniżej.

a <- currency$new("USD", 10)
a$currencyRates("USD")

             [,1]
2021-04-21 3.7950
2021-04-22 3.7885
2021-04-23 3.7855
2021-04-26 3.7657
2021-04-27 3.7826
2021-04-28 3.7939
2021-04-29 3.7786
2021-04-30 3.7746
2021-05-04 3.7940
2021-05-05 3.8136

W powyższy przykładzie został stworzony nowy obiekt dla dolara amerykańskiego, który zawiera ostatnich 10 notowań. Następnie została wykorzystana metoda currencyRates(), która pozwala na wyjęcie pobranych kursów z obiektu. Obie te metody muszą być zabiezpieczone w tym sensie, że jeżeli będziemy chcieli pozykać kursy dla waluty, która nie istnieje albo będziemy chcieli pozyskać zbyt dużo notować (API NBP posiada swoje ograniczenia) to dostaniemy komunikat o błędzie. Podobnie, jeżeli będziemy chcieli z obiektu wyjąć kursy dla waluty, której tam nie ma to również powinniśmy uzyskać komunikat o błędzie. Poniżej jest przykład ilustrujący taką funkcjonalność.

### Nie jest możliwe pozyskanie danych dla waluty KRA
a <- currency$new("KRA", 10)

### Nie jest możliwe pozyskanie 500 notowań
a <- currency$new("USD", 500)

### Poprawnie stworzony obiekt
a <- currency$new("USD", 100)

### Niepoprawnie podana waluta
a$currencyRates("GBP")

Error in initialize(...) : Wrong currency code or too many observations.
Error in initialize(...) : Wrong currency code or too many observations.
Error in a$currencyRates("GBP") : Currency not in the list

Klasa currency musi zapewniać możliwość dodawania wielu walut do istniejących obiektów (obiekt może zawierać notowania dla wielu walut). Oczywiście musimy dodać również możliwość usuwania walut i sprawdzania jakie waluty są w danym obiekcie. Poniżej jest przykład ilustrujący taką funkcjonalność.

### Tworzenie obiektu
a <- currency$new("USD", 100)

### Listowanie dodanych walut
a$currencyList()

### Dodawanie kolejnych dwóch walut
a$currencyAdd("EUR", 100)
a$currencyAdd("GBP", 100)
a$currencyList()

### Usuwanie wybranej waluty
a$currencyRemove("USD")
a$currencyList()

[[1]]
[1] "USD"
[[1]]
[1] "USD"

[[2]]
[1] "EUR"

[[3]]
[1] "GBP"
[[1]]
[1] "EUR"

[[2]]
[1] "GBP"

Ostatecznie chcemy również mieć możliwość prostej wizualizacji notawań zapisany w danym obiekcie. Służą do tego metody chart() oraz chartAdd(). Piersza z nich tworzy wykres dla podanej waluty natomiast druga dodaje do istniejącego wykresu wykres dla dodatkowych walut. Poniżej jest przykład ilustrujący taką funkcjonalność.

### Tworzenie obiektu
a <- currency$new("USD", 100)
a$currencyAdd("EUR", 100)
a$currencyAdd("GBP", 100)
a$currencyList()

### Tworzenie podstawowego wykresu
a$chart(currencyCode = "GBP", ylim = c(4.8, 5.6), col = "red", type = "o", pch = 4)
dev.copy(device = png, "./fig1.png")
dev.off()

### Dodawanie dodatkowych walut
a$chartAdd(currencyCode = "EUR", col = "blue", lwd = 4)
dev.copy(device = png, "./fig2.png")
dev.off()

a$chartAdd(currencyCode = "USD", col = "orange", lwd = 4)
dev.copy(device = png, "./fig3.png")
dev.off()

Stworzone wykresy są pokazane poniżej.

drawing.png

Figure 1: Utworzone wykresy w kolejności od lewej do prawej

Dodanie do istniejącego wykresu wykresu dla dodatkowej waluty powoduje automatycznie przeskalowanie wykresu ale jedocześnie nie są zapominane style, które zostały zasotosowane do poprzednio dodanych elementów wykresu. Oczywiście obie metody powinny być zabezpieczone przed sytuacją, gdzie podana waluta nie istnieje. Warto również zauważyć, że ponieważ wykres jest automatycznie przeskalowany to metody te muszą filtrować opcje, które są podawane przez użytkownika, w szczególności opcja ylim nie może być uwzględniona. Poniżej jest taki przykład.

### Tworzenie obiektów
a <- currency$new("USD", 100)
a$currencyAdd("EUR", 100)
a$currencyAdd("GBP", 100)

### Tworzenie podstawowego wykresu
a$chart(currencyCode = "GBP", ylim = c(4.8, 5.6), col = "red", type = "o", pch = 4)

### Dodawanie dodatkowych walut
a$chartAdd(currencyCode = "EUR", col = "blue", lwd = 4, ylim = c(-100, 100))
a$chartAdd(currencyCode = "USD", col = "orange", lwd = 4, main = "Przykładowy wykres")
dev.copy(device = png, "./fig4.png")
dev.off()

Poniżej jest uzyskany wykres.

fig4.png

Figure 2: Wykres pokazujący wynik filtrowania opcji

Jak widać pomimo podania bardzo dużego zakresu dla osi y oraz tytułu wykresy, obie te opcje zostały odfiltrowane.

Techniczne warunki zaliczenia

Zadanie powinno być rozwiązane w pojedynczym skrypcie w pliku R. Rozwiązanie powinno zawierać odpowiednie definicje oraz przykładowe wykorzystanie (podobne do tych pokazanych poniżej, mogą być identyczne) zaproponowanych rozwiązań. Rozwiązania bez przykładów nie będą zaliczane. W rozwiązaniu nie wolno wykorzystywać dodatkowych pakietów poza pakietami httr, jsonlite oraz jakimiś pakietami do przechowywania szeregów czasowych, np. zoo albo xts. Jeżeli będą Państwo stosowali model obiektowy R6 to oczywiście trzba wykorzystać pakiet R6. Proszę nie używać polskich znaków.

Data: 2021-05-01 Sat 00:00

Autor: Michał Ramsza

Created: 2021-05-05 Wed 23:18

Validate