#include "BitcoinExchange.hpp" void isDate(std::string date); BitcoinExchange::BitcoinExchange() { std::ifstream data("data.csv"); if (data.is_open()) { std::string s; int i = 0; while (std::getline(data, s)) { if (i == 0 && s != "date,exchange_rate") { std::cout << "Error: Data need to start with \"date,exchange_rate\"" << std::endl; throw std::exception(); } else if (i > 0) { try { std::string date = s.substr(0, s.find(",")); if (date.size() < 10 || date.size() > 10) { std::cout << "Error: date invalid"; throw std::exception(); } else isDate(date); char *endPrice; double price = std::strtof(s.substr(s.find(",") + 1 , s.size()).c_str(), &endPrice); if (price < 0) { std::cout << "Error: price negatif"; throw std::exception(); } else if (i != 0 && *endPrice == '\0') mapBitcoin.insert(std::make_pair(date, price)); } catch (std::exception &e) { std::cout << " in data" << std::endl; throw std::exception(); } } i++; } data.close(); if (mapBitcoin.size() == 0) { std::cout << "Data file empty." << std::endl; throw std::exception(); } } else { std::cout << "Error data file." << std::endl; throw std::exception(); } } BitcoinExchange::~BitcoinExchange() { } BitcoinExchange::BitcoinExchange(const BitcoinExchange &bit) { *this = bit; } BitcoinExchange &BitcoinExchange::operator=(const BitcoinExchange &bit) { if (this != &bit) { this->mapBitcoin = bit.mapBitcoin; } return *this; } // if the month finish by 31 return true else return false bool finishMonth(int month) { if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) return true; return false; } bool isLeapYear(int year) { return (((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)); } void isDate(std::string date) { int year = std::atoi(date.substr(0, 4).c_str()); int month = std::atoi(date.substr(5, 7).c_str()); int day = std::atoi(date.substr(8, 10).c_str()); bool leapYear = isLeapYear(year); if (month < 1 || month > 12) { std::cout << "Error: Bad Month"; throw std::exception(); } if ( (day < 1) || (month == 2 && ((day > 28 && !leapYear) || (day > 29 && leapYear))) || (finishMonth(month) && day > 31) || (!finishMonth(month) && day > 30) ) { std::cout << "Error: Bad Day"; throw std::exception(); } if (year < 2009 || (year == 2009 && month == 1 && day < 2)) { std::cout << "Error: Too old date"; throw std::exception(); } } double getValue(std::string value) { char* endPtr; double newValue = std::strtod(value.c_str(), &endPtr); if (*endPtr != '\0') { std::cout << "Error: Bad value"; throw std::exception(); } if (newValue > 1000) { std::cout << "Error: Too High"; throw std::exception(); } if (newValue < 0) { std::cout << "Error: Negatif Number"; throw std::exception(); } return newValue; } void verification(std::string s) { int nbr = 0; for (size_t i = 0; i < s.size() && nbr <= 1; i++) if (s[i] == '|') nbr++; if (nbr > 1) { std::cout << "Error: There are too many '|' in the line"; throw std::exception(); } else if (nbr == 0) { std::cout << "Error: There aren't '|' in the line"; throw std::exception(); } if (s.substr(0, s.find(" ")).size() != 10) { std::cout << "Error: Bad date"; throw std::exception(); } if (s.substr(s.find("|") + 1, s.size()).size() <= 0) { std::cout << "Error: Bad value"; throw std::exception(); } } // True if d1 is older or equal than d2 bool olderDate(std::string d1, std::string d2) { int year1 = std::atoi(d1.substr(0, 4).c_str()); int month1 = std::atoi(d1.substr(5, 7).c_str()); int day1 = std::atoi(d1.substr(8, 10).c_str()); int year2 = std::atoi(d2.substr(0, 4).c_str()); int month2 = std::atoi(d2.substr(5, 7).c_str()); int day2 = std::atoi(d2.substr(8, 10).c_str()); if (year1 == year2) { if (month1 == month2) { if (day1 == day2) { return true; } else return (day1 < day2); } else return (month1 < month2); } else return (year1 < year2); } void BitcoinExchange::printBitcoinValue(std::string date, double value) { std::map::iterator it; std::string dateMap; double valueMap; double lastValueMap = 0; for (it = mapBitcoin.begin(); it != mapBitcoin.end(); ++it) { dateMap = it->first; valueMap = it->second; if (dateMap == date) break; else if (olderDate(date, dateMap)) { valueMap = lastValueMap; break; } lastValueMap = valueMap; } std::cout << date << " => " << value << " = " << value * valueMap << std::endl; } void BitcoinExchange::read(const std::string &file) { std::ifstream input(file.c_str()); int i = 0; if (input.is_open()) { std::string s; while (std::getline(input, s)) { if (i == 0) { if (s == "date | value") std::cout << "date | value" << std::endl; else { std::cout << "Error: File need to start with \"date | value\"" << std::endl; return ; } } else { try { verification(s); std::string date = s.substr(0, s.find("|") - 1); isDate(s.substr(0, s.find("|") - 1)); double value = getValue(s.substr(s.find("|") + 1, s.size())); printBitcoinValue(date, value); } catch (std::exception &e) { std::cout << " << Your input: " << s << std::endl; } } i++; } if (i == 0) std::cout << "Error: Empty file" << std::endl; } else { std::cout << "Error input file." << std::endl; throw std::exception(); } }