Постоянные переменные size_t, похоже, не работают. Могу ли я получить некоторые рекомендации по этому вопросу? - PullRequest
0 голосов
/ 29 октября 2019

Итак, мне нужно взять две переменные / буфера потока (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(&copy_sstream);

  std::cout << "TESTING: sales tax calculation: ";
  copy_sstream.str(in_sstream.str());
  TestCalculateSalesTax(&copy_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;
  }
}
...