Created
June 9, 2022 16:16
Revisions
-
alexradzin created this gist
Jun 9, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,27 @@ package com.exercise; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.Map; @JsonIgnoreProperties(ignoreUnknown = true) public class ExchangeRate { private final String base; private final Map<String, Double> rates; @JsonCreator public ExchangeRate(@JsonProperty("base") String base, @JsonProperty("rates") Map<String, Double> rates) { this.base = base; this.rates = rates; } public String getBase() { return base; } public Map<String, Double> getRates() { return rates; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,10 @@ Implement code that calculates amounts of money in national currencies useing CSV file like Base,Sum,Target USD,100,ILS USD,150,GBP ... Use exchangeratesapi.io to retrieve currency rates. Print resutls to STDOUT. (Interview question of Correlate) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,98 @@ package com.exercise; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.logging.log4j.util.BiConsumer; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; import static java.lang.String.format; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; public class SumCalculator { private static final String RATES_URL_TEMPLATE = "https://api.exchangeratesapi.io/latest?base=%s&symbols=%s&access_key=d6943c813d6c3a3d1ca6793e8232a096"; private final ObjectMapper mapper = new ObjectMapper(); public List<Double> sums(InputStream transactions) throws IOException { if(!transactions.markSupported()) { throw new IllegalArgumentException("Given input stream does not support mark"); } transactions.mark(Integer.MAX_VALUE); Map<String, List<String>> currencies = retrieveAllUsedCurrencies(transactions); transactions.reset(); Map<String, Map<String, Double>> rates = getRates(currencies).stream().collect(toMap(ExchangeRate::getBase, ExchangeRate::getRates)); return calculate(transactions, rates); } private List<Double> calculate(InputStream transactions, Map<String, Map<String, Double>> rates) throws IOException { List<Double> results = new LinkedList<>(); return readTransactions(transactions, results, (results1, transaction) -> { String base = transaction.getBase(); String target = transaction.getTarget(); int sum = transaction.getSum(); double rate = Optional.ofNullable(rates.get(base)).map(baseCurrency -> baseCurrency.get(target)).orElse(Double.NaN); double result = sum * rate; results.add(result); }); } private Map<String, List<String>> retrieveAllUsedCurrencies(InputStream transactions) throws IOException { Map<String, List<String>> currencies = new HashMap<>(); return readTransactions(transactions, currencies, (currencies1, transaction) -> { String base = transaction.getBase(); String target = transaction.getTarget(); currencies1.merge(base, List.of(target), (existingTargets, newTargets) -> Stream.concat(existingTargets.stream(), newTargets.stream()).collect(toList())); }); } private <T> T readTransactions(InputStream transactions, T result, BiConsumer<T, Transaction> adder) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(transactions)); boolean header = true; for (String line = reader.readLine(); line != null; line = reader.readLine()) { if (header) { header = false; continue; } Transaction transaction = parseLineToTransaction(line); adder.accept(result, transaction); } return result; } private List<ExchangeRate> getRates(Map<String, List<String>> currencyNames) throws IOException { List<ExchangeRate> exchangeRates = new LinkedList<>(); for (Map.Entry<String, List<String>> entry : currencyNames.entrySet()) { String base = entry.getKey(); String targets = String.join(",", entry.getValue()); String url = format(RATES_URL_TEMPLATE, base, targets); ExchangeRate exchangeRate = mapper.readValue(new URL(url), ExchangeRate.class); if (exchangeRate.getBase() != null) { exchangeRates.add(exchangeRate); } } return exchangeRates; } private Transaction parseLineToTransaction(String line) { String[] parts = line.split(","); return new Transaction(parts[0], Integer.parseInt(parts[1]), parts[2]); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,14 @@ package com.exercise; import java.io.IOException; import java.io.InputStream; import java.util.List; public class SumCalculatorCli { public static void main(String[] args) throws IOException { try (InputStream in = SumCalculatorCli.class.getResourceAsStream("/transactions.csv")) { List<Double> results = new SumCalculator().sums(in); System.out.println(results); } } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,25 @@ package com.exercise; public class Transaction { private final String base; private final int sum; private final String target; public Transaction(String base, int sum, String target) { this.base = base; this.sum = sum; this.target = target; } public String getBase() { return base; } public int getSum() { return sum; } public String getTarget() { return target; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,6 @@ Base,Sum,Target USD,100,ILS USD,150,GBP ILS,100,USD EUR,300,ETH CAD,50,KRW