Commit 05fa74d3 by Patryk Czarnik

Waluty - ostatnia wersja

parent 9dd220af
/target/
/.settings/
/.classpath
/.project
/*.iml
/.idea/
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pl.alx.kjava</groupId>
<artifactId>PC07-Waluty</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- Po zmianie konfiguracji, np. wersji Javy.
w Eclipse trzeba jeszcze:
- zapisać plik (!)
- wykonać polecenie Maven → Update Project, można skrótem Alt+F5
wyszukiwarki zależności:
http://search.maven.org
http://mvnrepository.com
-->
<dependencies>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>com.formdev</groupId>
<artifactId>flatlaf</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.23.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
package dodatkowe;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
public class Download {
public static void main(String[] args) {
// Aby pobrać dane z adresu sieciowego (URL), można użyć klasy URL, która jest częścią Java SE.
// Istnieją też bardzej rozbudowane biblioteki, np. Apache HTTP Client.
// URL działa w najprostszych przypadkach: gdy nie ma uwierzytelnienia, ciasteczek, przekierowań.
try {
URL url = new URL("https://www.alx.pl/pdf/bootcamp-java-xl/");
InputStream input = url.openStream();
// można w pętli czytać bajty operacjami read, ale tu użyjemy gotowej metody, która kopiuje bajty do pliku
long size = Files.copy(input, Paths.get("program_kursu.pdf"), StandardCopyOption.REPLACE_EXISTING);
System.out.println("Gotowe. Pobrano " + size + " bajtów.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
package dodatkowe;
import java.util.Scanner;
public class Kalkulator {
public static void main(String[] args) {
try(Scanner sc = new Scanner(System.in)) {
System.out.println("Podaj działanie, np. 2 + 2");
int x = sc.nextInt();
String op = sc.next();
int y = sc.nextInt();
var wynik = switch(op) {
case "+" -> x + y;
case "-" -> x - y;
case "*" -> x * y;
case "/" -> x / y;
default -> 0;
};
System.out.println("Wynik: " + wynik);
}
}
}
package hello;
public class Hello {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
package waluty.model;
public class BladPobieraniaWalut extends Exception {
public BladPobieraniaWalut() {
super();
}
public BladPobieraniaWalut(String message, Throwable cause) {
super(message, cause);
}
public BladPobieraniaWalut(String message) {
super(message);
}
public BladPobieraniaWalut(Throwable cause) {
super(cause.getMessage(), cause);
}
}
package waluty.model;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDate;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonValue;
public class PobieranieJSON {
private static final String ADRES_BAZOWY = "http://api.nbp.pl/api/exchangerates/tables/";
private PobieranieJSON() {
// aby nikt nie utworzył obiektu tej klasy
}
public static Tabela pobierzAktualneKursy() throws BladPobieraniaWalut {
return pobierzJsonZAdresu(ADRES_BAZOWY + "/a/?format=json");
}
public static Tabela pobierzKursyArchiwalne(String data) throws BladPobieraniaWalut {
return pobierzJsonZAdresu(ADRES_BAZOWY + "/a/" + data + "?format=json");
}
public static Tabela pobierzKursyArchiwalne(LocalDate data) throws BladPobieraniaWalut {
return pobierzKursyArchiwalne(data.toString());
}
private static Tabela pobierzJsonZAdresu(String adres) throws BladPobieraniaWalut {
try {
URL url = new URL(adres);
try(InputStream input = url.openStream()) {
return wczytajStream(input);
}
} catch (IOException e) {
throw new BladPobieraniaWalut("Błąd pobierania tabeli", e);
}
}
private static Tabela wczytajStream(InputStream input) {
try(JsonReader reader = Json.createReader(input)) {
// dokument zawiera [tablicę], a ta tablica zawiera {obiekt}
JsonArray array = reader.readArray();
JsonObject tabela = array.getJsonObject(0);
String numer = tabela.getString("no");
LocalDate data = LocalDate.parse(tabela.getString("effectiveDate"));
JsonArray waluty = tabela.getJsonArray("rates");
Tabela wynikowaTabela = new Tabela(numer, data);
for(JsonValue jsonValue : waluty) {
JsonObject jsonObject = jsonValue.asJsonObject();
Waluta waluta = new Waluta(jsonObject.getString("code"),
jsonObject.getString("currency"),
jsonObject.getJsonNumber("mid").bigDecimalValue());
wynikowaTabela.dodajWalute(waluta);
}
return wynikowaTabela;
}
}
}
package waluty.model;
import java.math.BigDecimal;
import java.util.Scanner;
public class PrzelicznikWalutKonsola {
public static void main(String[] args) {
try {
System.out.println("Pobieram aktualne kursy...");
Tabela tabela = PobieranieJSON.pobierzAktualneKursy();
System.out.println(tabela);
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("\nPodaj kod waluty");
String kod = sc.nextLine().trim().toUpperCase();
if(kod == null || kod.isEmpty())
break;
Waluta waluta = tabela.wyszukaj(kod);
if(waluta == null) {
System.out.println("Nie ma takiej waluty.");
continue;
}
System.out.println("Wybrana waluta: " + waluta.getNazwa());
System.out.println("Aktualny kurs " + waluta.getKurs());
System.out.println();
System.out.println("Podaj kwotę");
if(!sc.hasNextBigDecimal()) {
System.out.println("Nieprawidłowa kwota.");
continue;
}
BigDecimal kwota = sc.nextBigDecimal();
sc.nextLine();
System.out.println(kwota + " " + kod + " = "
+ waluta.przeliczNaZlote(kwota) + " PLN");
System.out.println(kwota + " PLN " + " = "
+ waluta.przeliczNaWalute(kwota) + " " + kod);
}
} catch (BladPobieraniaWalut e) {
e.printStackTrace();
}
}
}
package waluty.model;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class Tabela {
private final String numer;
private final LocalDate data;
private final List<Waluta> waluty = new ArrayList<>();
public Tabela(String numer, LocalDate data) {
this.numer = numer;
this.data = data;
}
public String getNumer() {
return numer;
}
public LocalDate getData() {
return data;
}
public List<Waluta> getWaluty() {
return waluty;
}
@Override
public String toString() {
return "Tabela nr " + numer + " z dnia " + data + ", " + waluty.size() + " walut";
}
public void dodajWalute(Waluta waluta) {
this.waluty.add(waluta);
}
public Waluta wyszukaj(String kod) {
for(Waluta waluta : waluty) {
if(waluta.getKod().equals(kod)) {
return waluta;
}
}
return null;
}
public String[] getKodyWalut() {
return this.waluty.stream()
.map(Waluta::getKod)
.sorted()
.toArray(String[]::new);
}
}
package waluty.model;
import java.math.BigDecimal;
import java.math.RoundingMode;
// Ta klasa jest "niemutowalna" (immutable), tzn. raz utworzony obiekt tej klasy nie może zmienić stanu.
// O takich klasach mówi się też "value object". Przykłady znanych klas: String, Integer, BigDecimal, LocalDate
public class Waluta {
private final String kod;
private final String nazwa;
private final BigDecimal kurs;
public Waluta(String kod, String nazwa, BigDecimal kurs) {
this.kod = kod;
this.nazwa = nazwa;
this.kurs = kurs;
}
public String getKod() {
return kod;
}
public String getNazwa() {
return nazwa;
}
public BigDecimal getKurs() {
return kurs;
}
@Override
public String toString() {
return kod + " (" + nazwa + "): " + kurs;
}
public BigDecimal przeliczNaZlote(BigDecimal kwotaWWalucie) {
// po pomnożeniu zaokrąglamy do 2 miejsc po przecinku
return kwotaWWalucie.multiply(kurs).setScale(2, RoundingMode.HALF_UP);
}
public BigDecimal przeliczNaWalute(BigDecimal kwotaWZlotych) {
// zaokrąglanie robi się od razu podczas dzielenia
return kwotaWZlotych.divide(kurs, 2, RoundingMode.HALF_UP);
}
}
package waluty.model;
public class WypiszAktualneKursy {
public static void main(String[] args) {
System.out.println("Zaczynam pobierać dane...");
try {
Tabela tabela = PobieranieJSON.pobierzAktualneKursy();
System.out.println("Udało się pobrać");
System.out.println(tabela);
for(Waluta waluta : tabela.getWaluty()) {
System.out.println(waluta);
}
} catch (BladPobieraniaWalut e) {
System.out.println("Nie udało się pobrać, bo: " + e.getMessage());
e.printStackTrace();
}
}
}
package waluty.model;
import static org.assertj.core.api.Assertions.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class TabelaTest {
private static final String PRZYKLADOWY_NUMER = "123/A/NBP/2022";
private static final LocalDate PRZYKLADOWA_DATA = LocalDate.of(2022, 9, 30);
private Tabela tabela;
@BeforeEach
void setUp() {
tabela = new Tabela(PRZYKLADOWY_NUMER, PRZYKLADOWA_DATA);
}
@Test
void testTabela() {
assertThat(tabela.getNumer()).isEqualTo(PRZYKLADOWY_NUMER);
assertThat(tabela.getData()).isEqualTo(PRZYKLADOWA_DATA);
assertThat(tabela.getWaluty()).isEmpty();
}
@Test
void testToString() {
assertThat(tabela).asString().isEqualTo("Tabela nr 123/A/NBP/2022 z dnia 2022-09-30, 0 walut");
}
@Test
void testDodajWalute() {
Waluta dolar = new Waluta("USD", "dolar", new BigDecimal("5.0000"));
Waluta euro = new Waluta("EUR", "euro", new BigDecimal("3.0000"));
tabela.dodajWalute(dolar);
tabela.dodajWalute(euro);
assertThat(tabela.getWaluty())
.hasSize(2)
.containsExactlyInAnyOrder(dolar, euro);
}
@Test
void testWyszukaj() {
Waluta dolar = new Waluta("USD", "dolar", new BigDecimal("5.0000"));
Waluta euro = new Waluta("EUR", "euro", new BigDecimal("3.0000"));
tabela.dodajWalute(dolar);
tabela.dodajWalute(euro);
Waluta znaleziona = tabela.wyszukaj("EUR");
assertThat(znaleziona).isEqualTo(euro);
}
}
package waluty.model;
// import static org.junit.jupiter.api.Assertions.*;
import static org.assertj.core.api.Assertions.*;
import java.math.BigDecimal;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class WalutaTest {
private Waluta dolar;
private Waluta euro;
private Waluta peso;
@BeforeEach
void setUp() {
dolar = new Waluta("USD", "dolar", new BigDecimal("5.0000"));
euro = new Waluta("EUR", "euro", new BigDecimal("3.0000"));
peso = new Waluta("MXN", "peso", new BigDecimal("0.3333"));
}
@Test
void testWaluta() {
// asercje w stylu JUnit:
// assertEquals("USD", dolar.getKod());
// asersje w stylu AssertJ:
assertThat(dolar.getKod()).isEqualTo("USD");
// tylko prezentacja ciekawych asercji (akurat tutaj dla String)
assertThat(dolar.getKod())
.isNotNull()
.hasSize(3)
.isUpperCase()
.startsWith("U")
.endsWith("D");
}
@Test
void testToString() {
// assertEquals("USD (dolar): 5.0000", dolar.toString());
assertThat(dolar.toString()).isEqualTo("USD (dolar): 5.0000");
assertThat(euro.toString()).isEqualTo("EUR (euro): 3.0000");
}
@Test
void testPrzeliczNaZlote() {
BigDecimal sto = new BigDecimal("100.00");
BigDecimal wynik = dolar.przeliczNaZlote(sto);
assertThat(wynik).isEqualTo("500.00");
}
@Test
void testPrzeliczNaZloteZaokr() {
BigDecimal dwa = new BigDecimal("2.00");
BigDecimal wynik = peso.przeliczNaZlote(dwa);
assertThat(wynik).isEqualTo("0.67");
}
@Test
void testPrzeliczNaWalute() {
BigDecimal piescset = new BigDecimal("500.00");
BigDecimal wynik = dolar.przeliczNaWalute(piescset);
assertThat(wynik).isEqualTo("100.00");
}
@Test
void testPrzeliczNaWaluteZaokr() {
BigDecimal tysiac = new BigDecimal("2000.00");
BigDecimal wynik = euro.przeliczNaWalute(tysiac);
assertThat(wynik).isEqualTo("666.67");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment