Implement BitcoinExchange class with file handling and data processing
- Added BitcoinExchange class to manage Bitcoin data. - Implemented methods for loading data from files and processing input. - Introduced exception handling for various error scenarios (file not found, line format issues, negative values, etc.). - Created a main function to demonstrate usage and handle command-line arguments. - Added input data file with various test cases for validation.
This commit is contained in:
parent
d1ee3b830c
commit
8d6e32b681
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,4 +2,5 @@
|
||||
*.d
|
||||
*.o
|
||||
PmergeMe
|
||||
RPN
|
||||
RPN
|
||||
ex00/btc
|
||||
|
||||
2
ex00/Makefile
Normal file
2
ex00/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
NAME := btc
|
||||
include ../common.mk
|
||||
1613
ex00/dat2a.csv
Normal file
1613
ex00/dat2a.csv
Normal file
File diff suppressed because it is too large
Load Diff
62
ex00/inc/BitcoinExchange.hpp
Normal file
62
ex00/inc/BitcoinExchange.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <ctime>
|
||||
#include <exception>
|
||||
|
||||
class BitcoinExchange
|
||||
{
|
||||
public:
|
||||
BitcoinExchange() = delete;
|
||||
BitcoinExchange(const std::string &data_file);
|
||||
BitcoinExchange(const BitcoinExchange &other);
|
||||
~BitcoinExchange();
|
||||
BitcoinExchange &operator=(const BitcoinExchange &other);
|
||||
|
||||
void printData() const;
|
||||
void loadInputFile(const std::string &filename);
|
||||
|
||||
class FileNotFoundException : public std::exception
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const noexcept;
|
||||
};
|
||||
|
||||
class LineFormatException : public std::exception
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const noexcept;
|
||||
};
|
||||
|
||||
class ValueNegativeException : public std::exception
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const noexcept;
|
||||
};
|
||||
|
||||
class ValueTooLargeException : public std::exception
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const noexcept;
|
||||
};
|
||||
|
||||
class DateInvalidException : public std::exception
|
||||
{
|
||||
public:
|
||||
virtual const char *what() const noexcept;
|
||||
};
|
||||
|
||||
private:
|
||||
std::map<long, float>
|
||||
_data;
|
||||
long getTimestamp(const std::string &date) const;
|
||||
void loadDataFile(const std::string &filename);
|
||||
float getRate(long timestamp) const;
|
||||
float getValue(long timestamp, float amount) const;
|
||||
};
|
||||
16
ex00/input.txt
Normal file
16
ex00/input.txt
Normal file
@ -0,0 +1,16 @@
|
||||
date | value
|
||||
2011-01-03 | 3
|
||||
2011-01-03 | 2
|
||||
2011-01-03 | 1
|
||||
2011-01-03 | 1.2
|
||||
2011-01-09 | 1
|
||||
2016-04-12 | 3
|
||||
|
||||
2025-12-12 |2
|
||||
2012-01-11 | -1
|
||||
2001-42-42 | 2
|
||||
2000-01-11 | 1
|
||||
2012-01-11 | 2147483648
|
||||
2012-01-11 | 1
|
||||
2001-123-1 | 3
|
||||
|
||||
171
ex00/src/BitcoinExchange.cpp
Normal file
171
ex00/src/BitcoinExchange.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
#include "BitcoinExchange.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
BitcoinExchange::BitcoinExchange(const std::string &data_file)
|
||||
{
|
||||
loadDataFile(data_file);
|
||||
}
|
||||
|
||||
BitcoinExchange::BitcoinExchange(const BitcoinExchange &other) : _data(other._data)
|
||||
{
|
||||
}
|
||||
|
||||
BitcoinExchange::~BitcoinExchange()
|
||||
{
|
||||
}
|
||||
|
||||
BitcoinExchange &BitcoinExchange::operator=(const BitcoinExchange &other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
_data = other._data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void BitcoinExchange::printData() const
|
||||
{
|
||||
for (std::map<long, float>::const_iterator it = _data.begin(); it != _data.end(); ++it)
|
||||
{
|
||||
std::cout << it->first << " => " << it->second << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void trimInPlace(std::string &str)
|
||||
{
|
||||
// Trim from right
|
||||
str.erase(str.find_last_not_of(" \t\n\r") + 1);
|
||||
|
||||
// Trim from left
|
||||
str.erase(0, str.find_first_not_of(" \t\n\r"));
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> split(const std::string &str, char delimiter)
|
||||
{
|
||||
size_t pos = str.find(delimiter);
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
throw BitcoinExchange::LineFormatException();
|
||||
}
|
||||
|
||||
std::string first = str.substr(0, pos);
|
||||
std::string second = str.substr(pos + 1);
|
||||
|
||||
trimInPlace(first);
|
||||
trimInPlace(second);
|
||||
|
||||
if (first.empty() || second.empty())
|
||||
{
|
||||
throw BitcoinExchange::LineFormatException();
|
||||
}
|
||||
if (second.find_first_not_of("-0123456789.") != std::string::npos)
|
||||
{
|
||||
throw BitcoinExchange::LineFormatException();
|
||||
}
|
||||
|
||||
return {first, second};
|
||||
}
|
||||
|
||||
void BitcoinExchange::loadDataFile(const std::string &filename)
|
||||
{
|
||||
std::ifstream rate_file(filename);
|
||||
if (!rate_file)
|
||||
throw FileNotFoundException();
|
||||
|
||||
std::string line;
|
||||
std::getline(rate_file, line);
|
||||
while (std::getline(rate_file, line))
|
||||
{
|
||||
try
|
||||
{
|
||||
std::pair<std::string, std::string> parts = split(line, ',');
|
||||
long timestamp = getTimestamp(parts.first);
|
||||
float value = std::stof(parts.second);
|
||||
_data[timestamp] = value;
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BitcoinExchange::loadInputFile(const std::string &filename)
|
||||
{
|
||||
std::ifstream input_file(filename);
|
||||
if (!input_file)
|
||||
throw FileNotFoundException();
|
||||
|
||||
std::string line;
|
||||
std::getline(input_file, line);
|
||||
while (std::getline(input_file, line))
|
||||
{
|
||||
if (line.empty())
|
||||
continue;
|
||||
try
|
||||
{
|
||||
std::pair<std::string, std::string> parts = split(line, '|');
|
||||
long timestamp = getTimestamp(parts.first);
|
||||
float value = std::stof(parts.second);
|
||||
if (value < 0)
|
||||
throw ValueNegativeException();
|
||||
if (value > 1000)
|
||||
throw ValueTooLargeException();
|
||||
std::cout << parts.first << " => " << getValue(timestamp, value) << std::endl;
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float BitcoinExchange::getRate(long timestamp) const
|
||||
{
|
||||
auto it = _data.upper_bound(timestamp);
|
||||
if (it != _data.begin())
|
||||
--it;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
float BitcoinExchange::getValue(long timestamp, float amount) const
|
||||
{
|
||||
return getRate(timestamp) * amount;
|
||||
}
|
||||
|
||||
long BitcoinExchange::getTimestamp(const std::string &date) const
|
||||
{
|
||||
std::stringstream ss(date);
|
||||
std::tm tm = {};
|
||||
ss >> std::get_time(&tm, "%Y-%m-%d");
|
||||
if (ss.fail())
|
||||
throw std::invalid_argument("Error: Invalid date format: " + std::string(date));
|
||||
return static_cast<long>(std::mktime(&tm));
|
||||
}
|
||||
|
||||
const char *BitcoinExchange::FileNotFoundException::what() const noexcept
|
||||
{
|
||||
return "Error: File not found";
|
||||
}
|
||||
|
||||
const char *BitcoinExchange::LineFormatException::what() const noexcept
|
||||
{
|
||||
return "Error: Line format is incorrect";
|
||||
}
|
||||
|
||||
const char *BitcoinExchange::ValueNegativeException::what() const noexcept
|
||||
{
|
||||
return "Error: Value is negative";
|
||||
}
|
||||
const char *BitcoinExchange::ValueTooLargeException::what() const noexcept
|
||||
{
|
||||
return "Error: Value is too large";
|
||||
}
|
||||
|
||||
const char *BitcoinExchange::DateInvalidException::what() const noexcept
|
||||
{
|
||||
return "Error: Date is invalid";
|
||||
}
|
||||
31
ex00/src/main.cpp
Normal file
31
ex00/src/main.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "BitcoinExchange.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "Usage: " << argv[0] << " <data_file>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BitcoinExchange btcExchange("data.csv");
|
||||
btcExchange.loadInputFile(argv[1]);
|
||||
}
|
||||
catch (const BitcoinExchange::FileNotFoundException &e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cerr << "An error occurred: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
0
ex02/src/PmergeMe.cpp
Normal file
0
ex02/src/PmergeMe.cpp
Normal file
Loading…
Reference in New Issue
Block a user