Итак, мне нужно взять две переменные / буфера потока (in_stream) и поместить их в какой-то контейнер. Я выбрал список строк, который принимает оба буфера, а затем возвращает true. Затем я должен извлечь sales_tax из каждого штата, а затем вернуть налог штата.
Вот как должен выглядеть вывод, но мой факт выключен.
make clean && make test
rm -f lib/*
rm -f bin/*
g++ -std=c++11 -Wall -I inc -c -o lib/test_sales_tax_calculator.o src/test_sales_tax_calculator.cc
g++ -std=c++11 -Wall -I inc -c -o lib/sales_tax_calculator.o src/sales_tax_calculator.cc
g++ -std=c++11 -Wall -I inc -o bin/test_sales_tax_calculator lib/test_sales_tax_calculator.o lib/sales_tax_calculator.o
./bin/test_sales_tax_calculator < data/state_sales_taxes.txt
seed: 1572313602
TESTING: static sales tax extraction: FAILED
Expected: 5.6 Actual: 5
TESTING: sales tax calculation: FAILED
Expected: -2.3408 Actual: -2.09
заголовочный файл
#ifndef _INC_SALES_TAX_CALCULATOR_H_ // NOLINT
#define _INC_SALES_TAX_CALCULATOR_H_ // NOLINT
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <cstddef>
// using size_t
#include <istream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
class StateSalesTaxCalculator {
public:
static std::string state_list;
static std::string tax_list;
static std::string state_sales_tax_list;
static bool ExtractStatesTaxes(size_t no_of_states, std::istream& in_stream);
StateSalesTaxCalculator(const std::string& state_abbreviation);
double CalculateTax(double price) const;
double GetTax() const;
private:
int state_tax;
};
const size_t kLine_length = 2;
const size_t kState_length = 2;
const size_t kTax_length = 2.0;
#endif // NOLINT
.cc file
#include <sales_tax_calculator.h> // NOLINT
#include <test_sales_tax_calculator.h> // NOLINT
std::string StateSalesTaxCalculator::tax_list;
bool StateSalesTaxCalculator::ExtractStatesTaxes(
size_t no_of_states, std::istream& in_stream) {
std::string state_variable, tax_variable;
for (size_t i = 0; i < no_of_states; i++) {
in_stream >> state_variable;
in_stream >> tax_variable;
StateSalesTaxCalculator::tax_list += state_variable + tax_variable; // concatenates both states and taxes into one big string
}
return true;
}
StateSalesTaxCalculator::StateSalesTaxCalculator(
const std::string& state_abbreviation) {
for (size_t i = 0; i < kNo_of_states * kLine_length; i += kLine_length) {
if (tax_list.substr(i, kState_length) == state_abbreviation)
// checks the big string list and sees if the length of the
// states (2) is equal to the abbreviations of the states (2)
state_tax = stod(tax_list.substr(i+kState_length, kTax_length));
// checks the big string list and looks for the sales tax
// and then converts the tax_length 2 to a doulbe
}
}
double StateSalesTaxCalculator::CalculateTax(double price) const {
/* Calculates the State sales tax for the given price */
return price * GetTax() / 100;
}
double StateSalesTaxCalculator::GetTax() const {
/* Returns the percent State sales tax for the State */
return state_tax;
}
Вот также два других файла (test.h и test.cc), которые поставляются сэти два других файла.
тестовый файл заголовка
#ifndef _CSCS240_HW4_TEST_SALES_TAX_CALCULATOR_H_ //NOLINT
#define _CSCS240_HW4_TEST_SALES_TAX_CALCULATOR_H_ //NOLINT
#include <sales_tax_calculator.h>
#include <cmath>
// using fabs
#include <cstddef>
// using size_t
#include <cstdlib>
// using srand
// using rand
#include <ctime>
// using time
// using time_t
#include <iostream>
#include <istream>
#include <limits>
#include <ostream>
#include <sstream>
#include <string>
#include <vector>
bool TestCalculatorStateTaxes(std::istream*);
bool TestCalculateSalesTax(std::istream*);
const size_t kNo_of_states = 50;
void CopyStream(std::istream*, std::ostream*);
bool fpeq(double a, double b, double epsilon = 0.000001);
#endif //NOLINT
.cc тестовый файл
#include <test_sales_tax_calculator.h>
int main(int argc, char* argv[]) {
// log value and seed random sequence
time_t seed = time(NULL);
std::cout << "seed: " << seed << std::endl;
srand(seed);
// copy contents of STDIN to a stringstream instance
std::stringstream copy_sstream, in_sstream;
CopyStream(&(std::cin), &in_sstream);
// load StateSalesTaxCalculator class with stream contents
copy_sstream.str(in_sstream.str());
StateSalesTaxCalculator::ExtractStatesTaxes(kNo_of_states, copy_sstream);
std::cout << "TESTING: static sales tax extraction: ";
copy_sstream.str(in_sstream.str());
TestCalculatorStateTaxes(©_sstream);
std::cout << "TESTING: sales tax calculation: ";
copy_sstream.str(in_sstream.str());
TestCalculateSalesTax(©_sstream);
return 0;
}
bool TestCalculatorStateTaxes(std::istream* in_stream) {
std::string buffer;
for (size_t i = 0; i < kNo_of_states; ++i) {
// build a calculator with a state
*in_stream >> buffer;
StateSalesTaxCalculator test_calc(buffer);
// inspect state sales tax in calculator
*in_stream >> buffer;
double expected = std::stod(buffer);
double actual = test_calc.GetTax();
if (expected != actual) {
std::cout << "FAILED\n\tExpected: " << expected
<< " Actual: " << actual << std::endl;
return false;
}
}
std::cout << "PASSED" << std::endl;
return true;
}
bool TestCalculateSalesTax(std::istream* in_stream) {
std::string buffer;
for (size_t i = 0; i < kNo_of_states; ++i) {
// build a calculator with a state
*in_stream >> buffer;
StateSalesTaxCalculator test_calc(buffer);
// test state sales tax with calculator
*in_stream >> buffer;
int sign = (rand()%2 == 0 ? 1 : -1); //NOLINT
int singles = rand()%1000 + 1; // [1, 1000] //NOLINT
double cents = 0.01*(rand()%100); // [0.0, 0.99] //NOLINT
double expected = sign*(singles + cents)*0.01*std::stod(buffer);
double actual = test_calc.CalculateTax(sign*(singles + cents));
if (!fpeq(expected, actual)) {
std::cout << "FAILED\n\tExpected: " << expected
<< " Actual: " << actual << std::endl;
return false;
}
}
std::cout << "PASSED" << std::endl;
return true;
}
void CopyStream(std::istream* from_stream, std::ostream* to_stream) {
std::string buffer;
for (size_t i = 0; i < kNo_of_states; ++i) {
*from_stream >> buffer;
*to_stream << buffer << " ";
*from_stream >> buffer;
*to_stream << buffer << "\n";
}
}
bool fpeq(double a, double b, double epsilon) {
if (a == b) // trivially true
return true;
double abs_a = fabs(a);
double abs_b = fabs(b);
double diff = fabs(a - b);
if (a == 0 || b == 0 || abs_a + abs_b < std::numeric_limits<double>::min()) {
// when a or b is zero or both are extremely close to zero
// relative error is less meaningful
return diff < (epsilon*std::numeric_limits<double>::min());
} else { // use relative error
return diff / fmin((abs_a + abs_b), std::numeric_limits<double>::max())
< epsilon;
}
}