From 8f7cec9955c90cf03e6c0d0f6832ac868c6d4606 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 11 Dec 2019 10:34:02 +0200 Subject: [PATCH 01/25] Add calc implementation with UT --- iproject.h | 3 ++ main.cc | 10 ++++ project.cc | 113 ++++++++++++++++++++++++++++++++++++++++++- project.h | 20 ++++++++ test/project_test.cc | 48 +++++++++++++++++- 5 files changed, 191 insertions(+), 3 deletions(-) diff --git a/iproject.h b/iproject.h index ec4452f..24a50f5 100644 --- a/iproject.h +++ b/iproject.h @@ -1,9 +1,12 @@ #pragma once +#include namespace dev{ class IProject { virtual int run() = 0; + virtual bool parse_string(const std::string& data) = 0; + virtual int calculate() = 0; }; } diff --git a/main.cc b/main.cc index 5b2357f..38782f4 100644 --- a/main.cc +++ b/main.cc @@ -1,5 +1,15 @@ #include "project.h" +#include int main() { + std::unique_ptr polish_calculator(new dev::Project); + + auto result = polish_calculator->run(); + if (result == std::numeric_limits::min()) { + std::cout << "Error occured while calculating!" << std::endl; + } else { + std::cout << (int)result << std::endl; + } + return 0; } diff --git a/project.cc b/project.cc index fdc1225..d50a49c 100644 --- a/project.cc +++ b/project.cc @@ -2,7 +2,118 @@ namespace dev { +namespace { + const int kUserInputLimit = 1000; +} + +Project::Project() { + +} + int Project::run() { - return 0; + char user_input[kUserInputLimit]; + std::cout << "Input expression -> "; + std::cin.getline(user_input, sizeof(user_input)); + parse_string(user_input); + return calculate(); +} + +bool Project::parse_string(const std::string& data) { + if (data.empty()) { + return false; + } + + numbers_.clear(); + operators_.clear(); + + std::istringstream data_stream(data); + std::string buffer; + while (std::getline(data_stream, buffer, ' ')) { + std::string math_operator = string_matches_operator(buffer); + if (!math_operator.empty()) { + operators_.push_back(math_operator); + } + + try { + int number = std::stoi(buffer); + numbers_.push_back(number); + } catch (const std::exception& exception) { + // KEK + } + } + return true; +} + +int Project::calculate() { + if (operators_.size() != numbers_.size() - 1) { + return std::numeric_limits::min(); + } + + for(const auto& math_operator : operators_) { + if (math_operator == "+") { + auto left_op = numbers_[numbers_.size() - 1]; + auto right_op = numbers_[numbers_.size() - 2]; + numbers_.pop_back(); + numbers_.pop_back(); + numbers_.push_back(add(left_op,right_op)); + } + + if (math_operator == "-") { + auto left_op = numbers_[numbers_.size() - 1]; + auto right_op = numbers_[numbers_.size() - 2]; + numbers_.pop_back(); + numbers_.pop_back(); + numbers_.push_back(dec(left_op,right_op)); + } + + if (math_operator == "*") { + auto left_op = numbers_[numbers_.size() - 1]; + auto right_op = numbers_[numbers_.size() - 2]; + numbers_.pop_back(); + numbers_.pop_back(); + numbers_.push_back(mul(left_op,right_op)); + } + + if (math_operator == "/") { + auto left_op = numbers_[numbers_.size() - 1]; + auto right_op = numbers_[numbers_.size() - 2]; + numbers_.pop_back(); + numbers_.pop_back(); + numbers_.push_back(div(left_op,right_op)); + } + } + return *numbers_.begin(); } + +const std::vector& Project::get_numbers() { + return numbers_; +} + +const std::vector& Project::get_operators() { + return operators_; +} + +std::string Project::string_matches_operator(const std::string& possible_operator) { + if (possible_operator != "*" && possible_operator != "+" && possible_operator != "-" && possible_operator != "/") { + return ""; + } + return possible_operator; +} + +int Project::add(int first, int second) { + return first + second; +} + +int Project::div(int first, int second) { + return first / second; +} + +int Project::dec(int first, int second) { + return first - second; +} + +int Project::mul(int first, int second) { + return first * second; +} + } // namespace dev diff --git a/project.h b/project.h index b5cc813..e995be7 100644 --- a/project.h +++ b/project.h @@ -1,11 +1,31 @@ #pragma once #include "iproject.h" +#include +#include +#include +#include +#include +#include namespace dev { class Project : public IProject { // IProject interface public: + Project(); int run(); + bool parse_string(const std::string& data); + int calculate(); + const std::vector& get_numbers(); + const std::vector& get_operators(); + std::string string_matches_operator(const std::string& possible_operator); + + int add(int first, int second); + int div(int first, int second); + int dec(int first, int second); + int mul(int first, int second); + private: + std::vector numbers_; + std::vector operators_; }; } // namespace dev diff --git a/test/project_test.cc b/test/project_test.cc index 5dbeb2f..a4589b6 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -11,8 +11,52 @@ class ProjectTest : public ::testing::Test { dev::Project project_; }; -TEST_F(ProjectTest, Run) { - ASSERT_EQ(0, project_.run()); +TEST_F(ProjectTest, ParseString) { + ASSERT_FALSE(project_.parse_string("")); + EXPECT_TRUE(project_.parse_string("5 5 +")); + std::vector expected_numbers = {5,5}; + std::vector expected_operators = {"+"}; + EXPECT_EQ(expected_numbers, project_.get_numbers()); + EXPECT_EQ(expected_operators, project_.get_operators()); +} + +TEST_F(ProjectTest, CalculateNothing) { + ASSERT_EQ(std::numeric_limits::min(), project_.calculate()); +} + +TEST_F(ProjectTest, CalculateNoOperators) { + ASSERT_TRUE(project_.parse_string("5 5")); + EXPECT_EQ(std::numeric_limits::min(), project_.calculate()); +} + +TEST_F(ProjectTest, CalculateNoNumbers) { + ASSERT_TRUE(project_.parse_string("+ - / *")); + EXPECT_EQ(std::numeric_limits::min(), project_.calculate()); +} + +TEST_F(ProjectTest, CalculateAdd) { + ASSERT_TRUE(project_.parse_string("5 5 +")); + EXPECT_EQ(10, project_.calculate()); +} + +TEST_F(ProjectTest, CalculateDecrease) { + ASSERT_TRUE(project_.parse_string("7 5 -")); + EXPECT_EQ(-2, project_.calculate()); +} + +TEST_F(ProjectTest, CalculateMultiply) { + ASSERT_TRUE(project_.parse_string("5 7 *")); + EXPECT_EQ(35, project_.calculate()); +} + +TEST_F(ProjectTest, CalculateDivide) { + ASSERT_TRUE(project_.parse_string("7 14 /")); + EXPECT_EQ(2, project_.calculate()); +} + +TEST_F(ProjectTest, CalculateAddMultiple) { + ASSERT_TRUE(project_.parse_string("14 7 3 4 + + +")); + EXPECT_EQ(28, project_.calculate()); } } // namespace testing From 0201f5407186739a96e105af4a5ececc3ffe94a5 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 11 Dec 2019 12:16:20 +0200 Subject: [PATCH 02/25] Enhance input/output handling --- iproject.h | 2 +- main.cc | 22 ++++++++++++++++++---- project.cc | 22 +++++++++++++--------- project.h | 2 +- test/project_test.cc | 32 +++++++++++++++++++++++++++----- 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/iproject.h b/iproject.h index 24a50f5..429a664 100644 --- a/iproject.h +++ b/iproject.h @@ -4,7 +4,7 @@ namespace dev{ class IProject { - virtual int run() = 0; + virtual int run(const std::string& user_input) = 0; virtual bool parse_string(const std::string& data) = 0; virtual int calculate() = 0; }; diff --git a/main.cc b/main.cc index 38782f4..afa7a13 100644 --- a/main.cc +++ b/main.cc @@ -1,15 +1,29 @@ #include "project.h" #include -int main() { - std::unique_ptr polish_calculator(new dev::Project); - - auto result = polish_calculator->run(); + +namespace { + const int kUserInputLimit = 1000; +} + +std::string handle_input() { + char user_input[kUserInputLimit]; + std::cout << "Input expression -> "; + std::cin.getline(user_input, sizeof(user_input)); + return std::string(user_input); +} + +void handle_output(int result) { if (result == std::numeric_limits::min()) { std::cout << "Error occured while calculating!" << std::endl; } else { std::cout << (int)result << std::endl; } +} +int main() { + std::unique_ptr polish_calculator(new dev::Project); + int result = polish_calculator->run(handle_input()); + handle_output(result); return 0; } diff --git a/project.cc b/project.cc index d50a49c..e1f4c91 100644 --- a/project.cc +++ b/project.cc @@ -3,19 +3,18 @@ namespace dev { namespace { - const int kUserInputLimit = 1000; + const auto kError = std::numeric_limits::min(); } Project::Project() { } -int Project::run() { - char user_input[kUserInputLimit]; - std::cout << "Input expression -> "; - std::cin.getline(user_input, sizeof(user_input)); - parse_string(user_input); - return calculate(); +int Project::run(const std::string& user_input) { + return parse_string(user_input) ? + calculate() + : + kError; } bool Project::parse_string(const std::string& data) { @@ -41,12 +40,17 @@ bool Project::parse_string(const std::string& data) { // KEK } } + + if (numbers_.empty() || operators_.empty()) { + return false; + } + return true; } int Project::calculate() { if (operators_.size() != numbers_.size() - 1) { - return std::numeric_limits::min(); + return kError; } for(const auto& math_operator : operators_) { @@ -105,7 +109,7 @@ int Project::add(int first, int second) { } int Project::div(int first, int second) { - return first / second; + return second ? first / second : kError; } int Project::dec(int first, int second) { diff --git a/project.h b/project.h index e995be7..b7cd4c7 100644 --- a/project.h +++ b/project.h @@ -13,7 +13,7 @@ class Project : public IProject { // IProject interface public: Project(); - int run(); + int run(const std::string& user_input); bool parse_string(const std::string& data); int calculate(); const std::vector& get_numbers(); diff --git a/test/project_test.cc b/test/project_test.cc index a4589b6..d2612f1 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -4,6 +4,10 @@ namespace dev { namespace testing { +namespace { + const auto kError = std::numeric_limits::min(); +} + class ProjectTest : public ::testing::Test { public: void SetUp() override {} @@ -13,6 +17,9 @@ class ProjectTest : public ::testing::Test { TEST_F(ProjectTest, ParseString) { ASSERT_FALSE(project_.parse_string("")); + ASSERT_FALSE(project_.parse_string(" 5 4 3 2 ")); + ASSERT_FALSE(project_.parse_string(" + - = * ")); + EXPECT_TRUE(project_.parse_string("5 5 +")); std::vector expected_numbers = {5,5}; std::vector expected_operators = {"+"}; @@ -21,17 +28,17 @@ TEST_F(ProjectTest, ParseString) { } TEST_F(ProjectTest, CalculateNothing) { - ASSERT_EQ(std::numeric_limits::min(), project_.calculate()); + ASSERT_EQ(kError, project_.calculate()); } TEST_F(ProjectTest, CalculateNoOperators) { - ASSERT_TRUE(project_.parse_string("5 5")); - EXPECT_EQ(std::numeric_limits::min(), project_.calculate()); + ASSERT_FALSE(project_.parse_string("5 5")); + EXPECT_EQ(kError, project_.calculate()); } TEST_F(ProjectTest, CalculateNoNumbers) { - ASSERT_TRUE(project_.parse_string("+ - / *")); - EXPECT_EQ(std::numeric_limits::min(), project_.calculate()); + ASSERT_FALSE(project_.parse_string("+ - / *")); + EXPECT_EQ(kError, project_.calculate()); } TEST_F(ProjectTest, CalculateAdd) { @@ -59,5 +66,20 @@ TEST_F(ProjectTest, CalculateAddMultiple) { EXPECT_EQ(28, project_.calculate()); } +TEST_F(ProjectTest, CalculateSeveralOperations) { + ASSERT_TRUE(project_.parse_string("4 4 4 4 + * -")); + EXPECT_EQ(28, project_.calculate()); +} + +TEST_F(ProjectTest, CalculateSeveralOperationsDifferentPlacementOrder) { + ASSERT_TRUE(project_.parse_string("1 2 + 4 * 3 +")); + EXPECT_EQ(15, project_.calculate()); +} + +TEST_F(ProjectTest, CalculateDividingZero) { + ASSERT_TRUE(project_.parse_string("0 1 /")); + EXPECT_EQ(kError, project_.calculate()); +} + } // namespace testing } // namespace dev From f6dbe9f5fc55d508ba3d35d4374b05d2fbe748fc Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 11 Dec 2019 13:43:44 +0200 Subject: [PATCH 03/25] Add TODO tips --- main.cc | 1 + project.cc | 10 ++++++++++ test/project_test.cc | 2 ++ 3 files changed, 13 insertions(+) diff --git a/main.cc b/main.cc index afa7a13..2a64549 100644 --- a/main.cc +++ b/main.cc @@ -6,6 +6,7 @@ namespace { const int kUserInputLimit = 1000; } +//TODO: Maybe add IO handler ?? std::string handle_input() { char user_input[kUserInputLimit]; std::cout << "Input expression -> "; diff --git a/project.cc b/project.cc index e1f4c91..22213b8 100644 --- a/project.cc +++ b/project.cc @@ -6,6 +6,7 @@ namespace { const auto kError = std::numeric_limits::min(); } +// TODO: Project must use separate objects for calculate() and parse_string() options Project::Project() { } @@ -17,6 +18,7 @@ int Project::run(const std::string& user_input) { kError; } +// TODO: Move this method to separate object. bool Project::parse_string(const std::string& data) { if (data.empty()) { return false; @@ -38,6 +40,9 @@ bool Project::parse_string(const std::string& data) { numbers_.push_back(number); } catch (const std::exception& exception) { // KEK + + // TODO: Figure out how to handle this exception + // (if it should be) } } @@ -48,11 +53,15 @@ bool Project::parse_string(const std::string& data) { return true; } +// TODO: Move this method to separate object. int Project::calculate() { if (operators_.size() != numbers_.size() - 1) { return kError; } + // TODO: Redefine numbers_ as custom stack + // with overrided 'pop' method. + // This will prevent double using of numbers_.pop_back() for(const auto& math_operator : operators_) { if (math_operator == "+") { auto left_op = numbers_[numbers_.size() - 1]; @@ -97,6 +106,7 @@ const std::vector& Project::get_operators() { return operators_; } +// TODO: Make next functions private. std::string Project::string_matches_operator(const std::string& possible_operator) { if (possible_operator != "*" && possible_operator != "+" && possible_operator != "-" && possible_operator != "/") { return ""; diff --git a/test/project_test.cc b/test/project_test.cc index d2612f1..57c19d5 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -8,6 +8,8 @@ namespace { const auto kError = std::numeric_limits::min(); } +//TODO: Add appropriate tests for each new component (Calculator / Parser) + class ProjectTest : public ::testing::Test { public: void SetUp() override {} From 95184e72885df944cef3859eb4741c6cd2ce03c9 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 11 Dec 2019 13:44:01 +0200 Subject: [PATCH 04/25] Add vim project settings --- .vimrc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .vimrc diff --git a/.vimrc b/.vimrc new file mode 100644 index 0000000..e40bae1 --- /dev/null +++ b/.vimrc @@ -0,0 +1,24 @@ +function! Build() + silent :!clear + silent :!mkdir -p build + silent :!cd build && cmake .. && make + :!echo "Done" + redraw! +endfunction +command! Build :call Build() + +function! Clean() + silent :!clear + silent :!cd build && rm -frv * + :!echo "Done" + redraw! +endfunction +command! Clean :call Clean() + +function! Run() + silent :!clear + silent :!cd build && ./project + :!echo "Done" + redraw! +endfunction +command! Run :call Run() From d19592b03e0005159228665cacb74357a1aeb8a2 Mon Sep 17 00:00:00 2001 From: KEK Date: Thu, 12 Dec 2019 11:55:21 +0200 Subject: [PATCH 05/25] Enhance vim settings --- .vimrc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.vimrc b/.vimrc index e40bae1..d1d53ee 100644 --- a/.vimrc +++ b/.vimrc @@ -22,3 +22,11 @@ function! Run() redraw! endfunction command! Run :call Run() + +function! Test() + silent :!clear + silent :!cd build/test && ./ProjectTest + :!echo "Done" + redraw! +endfunction +command! Test :call Test() From e2f4d09ea85c88d48e8b9f8b3ff5d7f345aa8184 Mon Sep 17 00:00:00 2001 From: KEK Date: Thu, 12 Dec 2019 13:46:33 +0200 Subject: [PATCH 06/25] Separate parsing unit tests --- test/project_test.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/project_test.cc b/test/project_test.cc index 57c19d5..07c02d5 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -17,11 +17,13 @@ class ProjectTest : public ::testing::Test { dev::Project project_; }; -TEST_F(ProjectTest, ParseString) { - ASSERT_FALSE(project_.parse_string("")); - ASSERT_FALSE(project_.parse_string(" 5 4 3 2 ")); - ASSERT_FALSE(project_.parse_string(" + - = * ")); - +TEST_F(ProjectTest, ParseString_FAILURE) { + EXPECT_FALSE(project_.parse_string("")); + EXPECT_FALSE(project_.parse_string(" 5 4 3 2 ")); + EXPECT_FALSE(project_.parse_string(" + - = * ")); +} + +TEST_F(ProjectTest, ParseString_SUCCESS) { EXPECT_TRUE(project_.parse_string("5 5 +")); std::vector expected_numbers = {5,5}; std::vector expected_operators = {"+"}; From f1dc4864e0ea6fefc5e12c85af7e0b2e4aad70ec Mon Sep 17 00:00:00 2001 From: KEK Date: Thu, 12 Dec 2019 13:47:43 +0200 Subject: [PATCH 07/25] Separate parsing and calculation to objects --- CMakeLists.txt | 4 +- Calculator/.Calculator.cc.swp | Bin 0 -> 12288 bytes Calculator/.Calculator.h.swp | Bin 0 -> 12288 bytes Calculator/Calculator.cc | 74 +++++++++++++++++++++++ Calculator/Calculator.h | 30 +++++++++ Calculator/ICalculator.h | 12 ++++ Parser/.Calculator.cc.swp | Bin 0 -> 12288 bytes Parser/.Calculator.h.swp | Bin 0 -> 12288 bytes Parser/.IParser.h.swp | Bin 0 -> 12288 bytes Parser/.Parser.cc.swp | Bin 0 -> 12288 bytes Parser/.Parser.h.swp | Bin 0 -> 12288 bytes Parser/IParser.h | 14 +++++ Parser/Parser.cc | 66 ++++++++++++++++++++ Parser/Parser.h | 31 ++++++++++ project.cc | 111 ++++------------------------------ project.h | 18 +++--- 16 files changed, 250 insertions(+), 110 deletions(-) create mode 100644 Calculator/.Calculator.cc.swp create mode 100644 Calculator/.Calculator.h.swp create mode 100644 Calculator/Calculator.cc create mode 100644 Calculator/Calculator.h create mode 100644 Calculator/ICalculator.h create mode 100644 Parser/.Calculator.cc.swp create mode 100644 Parser/.Calculator.h.swp create mode 100644 Parser/.IParser.h.swp create mode 100644 Parser/.Parser.cc.swp create mode 100644 Parser/.Parser.h.swp create mode 100644 Parser/IParser.h create mode 100644 Parser/Parser.cc create mode 100644 Parser/Parser.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e6318a3..ea29a31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,9 @@ project(dummy_cmake_project) set(CMAKE_CXX_STANDARD 14) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) -set(SOURCES project.cc) +include_directories("Calculator") +include_directories("Parser") +set(SOURCES project.cc Calculator/Calculator.cc Parser/Parser.cc) add_library(ProjectLib ${SOURCES}) add_executable(project main.cc) diff --git a/Calculator/.Calculator.cc.swp b/Calculator/.Calculator.cc.swp new file mode 100644 index 0000000000000000000000000000000000000000..d635c7ac465f79f71e75f62cd05364555bb73a46 GIT binary patch literal 12288 zcmeI2&5zqe7>B1wAifF+Zd8@trcxX4#>wtd3QD`nq2}IX}pC zc2<~ z18jf|uz@?!KoAM>`#nM|-ize%|NrUl|34nab?_7T5_|zZ2Uo%K;BN5SLqdEFz5<_t zPeBOQ!E@j=*blDl6=Dl~2vTqq{QIB~zk(mYC*TVB0L0)3xb}b$zku(-Rd5-+56*%W z@X!51{0zPYAA$G4yI>5Kz~A>Fcd!MnfOo*#U<4u%f}>zR*asd5f5O3c;2W?7J_hH( zCYXRzU3l0XDz}*Z>>YRR%6JO^6GENJ~@dltxMyh8C!hVU|Y6gh~xH zZ}Ro~Ng228wW?o->}lQAqqlAn$lozgB*Xav)#2$Gms-z7q&}T{R_jdvKgUQ-<_ld< zc5%lXgD9FW&_Y@!L#c~_zc!Q`Ds6kmpww!e{v~R<t0ZrjHcmemD;oPyw{qTg?dxAJ@RSgj7`?IYM{&K_T!e_I5nbn z5|}Y^m)gGXNvo^W>b0sT!iKFqTsNPY0sB1dQUeR~8L$gsmm2WrGhmn5E;X=N86X;E zx{ZR0(rVY(A-aCO^l4$bc8Y;rHblK1y*yS0ZK^n?T+4|>rH!(37)vS(m2OZrx@m!^ z$8IV!rfed$R*{V8aGvFdDUoKJMO_zt{p5O|UXqa^Yc7^FxzWd~&l9|?p1JeFXsBIVYf|v+M7M8%&3XNu zJA}hT5ys`xA&~}&Eb<_f6v@eSt8AVKx0j*lRykpu)G8drDp965Zi7KXy{|NpAnc$@ P!?=tjwVJ%T?LISE881)#MRbiLODhB{ld4M zRr*AoCQ;}fyG)rpGO?6-OIIdl5j`yvm!*rMgI;QqJr&sHjvodt^lf4)&DQQ;CgU(0 zU<1<|aCWeCZJsV&TwTcr)oTml%;~M^$8#ndU;}J`4X^<=zy{a=8(;%7Z@{K=^bDss zR-WX1S<~18jf|umLu}2G{@_U;{H~z?VdCj}zUT$L8_>|M>U+ zmy<;A!8`B>&uME^xEcJlskc2qAjz?ZHD?QJ}df%yDYRy{l zKE##hq-Z{5KD%KPTipYhHydG$i*=Es|sUV5v z;&}QzDpfE|mL5)#ZuPTjfz@mqB^&TQwF%GE~NBsmA*oouzpGgT#7OyL F{0I676V3nt literal 0 HcmV?d00001 diff --git a/Calculator/Calculator.cc b/Calculator/Calculator.cc new file mode 100644 index 0000000..b08b533 --- /dev/null +++ b/Calculator/Calculator.cc @@ -0,0 +1,74 @@ +#include "Calculator.h" + +namespace { + const auto kError = std::numeric_limits::min(); +} + +namespace dev { + Calculator::Calculator(std::unique_ptr> numbers, + std::unique_ptr> operators) + : numbers_(std::move(numbers)) + , operators_(std::move(operators)) { } + +int Calculator::calculate() { + + if (operators_->size() != numbers_->size() - 1) { + return kError; + } + + // TODO: Redefine numbers_ as custom stack + // with overrided 'pop' method. + // This will prevent double using of numbers_->pop_back() + for(const auto& math_operator : *operators_) { + if (math_operator == "+") { + auto left_op = (*numbers_)[numbers_->size() - 1]; + auto right_op = (*numbers_)[numbers_->size() - 2]; + numbers_->pop_back(); + numbers_->pop_back(); + numbers_->push_back(add(left_op,right_op)); + } + + if (math_operator == "-") { + auto left_op = (*numbers_)[numbers_->size() - 1]; + auto right_op = (*numbers_)[numbers_->size() - 2]; + numbers_->pop_back(); + numbers_->pop_back(); + numbers_->push_back(dec(left_op,right_op)); + } + + if (math_operator == "*") { + auto left_op = (*numbers_)[numbers_->size() - 1]; + auto right_op = (*numbers_)[numbers_->size() - 2]; + numbers_->pop_back(); + numbers_->pop_back(); + numbers_->push_back(mul(left_op,right_op)); + } + + if (math_operator == "/") { + auto left_op = (*numbers_)[numbers_->size() - 1]; + auto right_op = (*numbers_)[numbers_->size() - 2]; + numbers_->pop_back(); + numbers_->pop_back(); + numbers_->push_back(div(left_op,right_op)); + } + } + return *numbers_->begin(); +} + +int Calculator::add(int first, int second) { + return first + second; +} + +int Calculator::div(int first, int second) { + return second ? first / second : kError; +} + +int Calculator::dec(int first, int second) { + return first - second; +} + +int Calculator::mul(int first, int second) { + return first * second; +} + +} diff --git a/Calculator/Calculator.h b/Calculator/Calculator.h new file mode 100644 index 0000000..e436110 --- /dev/null +++ b/Calculator/Calculator.h @@ -0,0 +1,30 @@ +#ifndef CALCULATOR_CALCULATOR_H +#define CALCULATOR_CALCULATOR_H + +#include "ICalculator.h" + +#include +#include +#include +#include + +namespace dev { + + class Calculator : public ICalculator { + public: + Calculator(std::unique_ptr> numbers, + std::unique_ptr> operators); + int calculate() override; + + private: + int add(int first, int second); + int div(int first, int second); + int dec(int first, int second); + int mul(int first, int second); + + std::unique_ptr> numbers_; + std::unique_ptr> operators_; + }; +} + +#endif diff --git a/Calculator/ICalculator.h b/Calculator/ICalculator.h new file mode 100644 index 0000000..3361bf1 --- /dev/null +++ b/Calculator/ICalculator.h @@ -0,0 +1,12 @@ +#ifndef CALCULATOR_ICALCULATOR_H +#define CALCULATOR_ICALCULATOR_H + +namespace dev { + +class ICalculator { + public: + virtual int calculate() = 0; +}; + +} +#endif diff --git a/Parser/.Calculator.cc.swp b/Parser/.Calculator.cc.swp new file mode 100644 index 0000000000000000000000000000000000000000..2458b9184406fd254235a1ff4934524d341e146a GIT binary patch literal 12288 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 YNNZ{;VM`qoksD+lr%ut;qTgZv0K`kNlmGw# literal 0 HcmV?d00001 diff --git a/Parser/.Parser.h.swp b/Parser/.Parser.h.swp new file mode 100644 index 0000000000000000000000000000000000000000..2568d85fd28b8409c1f038bd23ab78ecfc892ade GIT binary patch literal 12288 zcmeI2O=}ZD7{{M@wkrAo9J3;g*tFV~mb3(<2-X)U6}?DV_GQvc*|+Y@hK5o-^fUMs z^r}a_dRLEr0l~B2-T!7MWoe~0Hw(|eFOzv@o|$KU<~18jf|umLu}2G{@_U<2pSfEN;dzDV?P3dQ69|MBzx&&x#L zz*q1Id<5^n8*m7A!4`M~7Qq6z2^`P>zb_H}03X16Fa*nB3ET$Xao$_710)E556U{8 zfX9Fv8(;%$fDNz#Hoykh02^QfY~a5$;K(FYJ;$kfJOowa(I?RX330H3kFseKb~;6( zb_?ldCSM(m2Y3xSwcoYLRkGdfiZqkChp=|flB*JfoTP|-c|4=q5hs@$yRm12zSQn` z`{^J}w5jTo38C1qPkv!sT1)(XaO6I literal 0 HcmV?d00001 diff --git a/Parser/IParser.h b/Parser/IParser.h new file mode 100644 index 0000000..75b840f --- /dev/null +++ b/Parser/IParser.h @@ -0,0 +1,14 @@ +#ifndef PARSER_IPARSER_H +#define PARSER_IPARSER_H + +#include + +namespace dev { + +class IParser { + public: + virtual bool parse(const std::string& data) = 0; +}; + +} +#endif diff --git a/Parser/Parser.cc b/Parser/Parser.cc new file mode 100644 index 0000000..b7ece1f --- /dev/null +++ b/Parser/Parser.cc @@ -0,0 +1,66 @@ +#include "Parser.h" + +namespace { + const auto kError = std::numeric_limits::min(); +} + +namespace dev { +Parser::Parser() + : numbers_(new std::vector()), + operators_(new std::vector()) { +} + +bool Parser::parse(const std::string& data) { + if (data.empty()) { + return false; + } + + numbers_->clear(); + operators_->clear(); + + std::istringstream data_stream(data); + std::string buffer; + while (std::getline(data_stream, buffer, ' ')) { + std::string math_operator = string_matches_operator(buffer); + if (!math_operator.empty()) { + operators_->push_back(math_operator); + } + + try { + int number = std::stoi(buffer); + numbers_->push_back(number); + } catch (const std::exception& exception) { + // KEK + + // TODO: Figure out how to handle this exception + // (if it should be) + } + } + + if (numbers_->empty() || operators_->empty()) { + return false; + } + + return true; +} + +std::string Parser::string_matches_operator(const std::string& possible_operator) { + if (possible_operator != "*" && + possible_operator != "+" && + possible_operator != "-" && + possible_operator != "/") { + return ""; + } + + return possible_operator; +} + +std::unique_ptr> Parser::get_numbers() { + return std::move(numbers_); +} + +std::unique_ptr> Parser::get_operators() { + return std::move(operators_); +} + +} diff --git a/Parser/Parser.h b/Parser/Parser.h new file mode 100644 index 0000000..7ee030a --- /dev/null +++ b/Parser/Parser.h @@ -0,0 +1,31 @@ +#ifndef PARSER_PARSER_H +#define PARSER_PARSER_H + +#include "IParser.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace dev { + + class Parser : public IParser { + public: + Parser(); + bool parse(const std::string& data) override; + + std::unique_ptr> get_numbers(); + std::unique_ptr> get_operators(); + + private: + std::string string_matches_operator(const std::string& possible_operator); + std::unique_ptr> numbers_; + std::unique_ptr> operators_; + }; +} + +#endif diff --git a/project.cc b/project.cc index 22213b8..02f165c 100644 --- a/project.cc +++ b/project.cc @@ -7,7 +7,7 @@ namespace { } // TODO: Project must use separate objects for calculate() and parse_string() options -Project::Project() { +Project::Project() : parser_(new Parser()){ } @@ -20,114 +20,25 @@ int Project::run(const std::string& user_input) { // TODO: Move this method to separate object. bool Project::parse_string(const std::string& data) { - if (data.empty()) { + if (!parser_) { return false; } - - numbers_.clear(); - operators_.clear(); - - std::istringstream data_stream(data); - std::string buffer; - while (std::getline(data_stream, buffer, ' ')) { - std::string math_operator = string_matches_operator(buffer); - if (!math_operator.empty()) { - operators_.push_back(math_operator); - } - - try { - int number = std::stoi(buffer); - numbers_.push_back(number); - } catch (const std::exception& exception) { - // KEK - - // TODO: Figure out how to handle this exception - // (if it should be) - } - } - - if (numbers_.empty() || operators_.empty()) { - return false; - } - - return true; + return parser_->parse(data); } // TODO: Move this method to separate object. int Project::calculate() { - if (operators_.size() != numbers_.size() - 1) { - return kError; - } - - // TODO: Redefine numbers_ as custom stack - // with overrided 'pop' method. - // This will prevent double using of numbers_.pop_back() - for(const auto& math_operator : operators_) { - if (math_operator == "+") { - auto left_op = numbers_[numbers_.size() - 1]; - auto right_op = numbers_[numbers_.size() - 2]; - numbers_.pop_back(); - numbers_.pop_back(); - numbers_.push_back(add(left_op,right_op)); - } - - if (math_operator == "-") { - auto left_op = numbers_[numbers_.size() - 1]; - auto right_op = numbers_[numbers_.size() - 2]; - numbers_.pop_back(); - numbers_.pop_back(); - numbers_.push_back(dec(left_op,right_op)); - } - - if (math_operator == "*") { - auto left_op = numbers_[numbers_.size() - 1]; - auto right_op = numbers_[numbers_.size() - 2]; - numbers_.pop_back(); - numbers_.pop_back(); - numbers_.push_back(mul(left_op,right_op)); - } - - if (math_operator == "/") { - auto left_op = numbers_[numbers_.size() - 1]; - auto right_op = numbers_[numbers_.size() - 2]; - numbers_.pop_back(); - numbers_.pop_back(); - numbers_.push_back(div(left_op,right_op)); - } - } - return *numbers_.begin(); + calculator_.reset(new Calculator(parser_->get_numbers(), + parser_->get_operators())); + return calculator_->calculate(); } -const std::vector& Project::get_numbers() { - return numbers_; +std::vector Project::get_numbers() { + return *parser_->get_numbers(); } -const std::vector& Project::get_operators() { - return operators_; -} - -// TODO: Make next functions private. -std::string Project::string_matches_operator(const std::string& possible_operator) { - if (possible_operator != "*" && possible_operator != "+" && possible_operator != "-" && possible_operator != "/") { - return ""; - } - return possible_operator; -} - -int Project::add(int first, int second) { - return first + second; -} - -int Project::div(int first, int second) { - return second ? first / second : kError; -} - -int Project::dec(int first, int second) { - return first - second; -} - -int Project::mul(int first, int second) { - return first * second; -} +std::vector Project::get_operators() { + return *parser_->get_operators(); +} } // namespace dev diff --git a/project.h b/project.h index b7cd4c7..7aeb426 100644 --- a/project.h +++ b/project.h @@ -1,11 +1,14 @@ #pragma once #include "iproject.h" +#include "Calculator/Calculator.h" +#include "Parser/Parser.h" #include #include #include #include #include #include +#include namespace dev { @@ -16,16 +19,13 @@ class Project : public IProject { int run(const std::string& user_input); bool parse_string(const std::string& data); int calculate(); - const std::vector& get_numbers(); - const std::vector& get_operators(); - std::string string_matches_operator(const std::string& possible_operator); - int add(int first, int second); - int div(int first, int second); - int dec(int first, int second); - int mul(int first, int second); + + std::vector get_numbers(); + std::vector get_operators(); + private: - std::vector numbers_; - std::vector operators_; + std::unique_ptr calculator_; + std::unique_ptr parser_; }; } // namespace dev From ce2c01258c061248011852e2f708a48936720e85 Mon Sep 17 00:00:00 2001 From: KEK Date: Tue, 17 Dec 2019 12:36:17 +0200 Subject: [PATCH 08/25] Refactor usage of numbers stack --- CMakeLists.txt | 1 + Calculator/Calculator.cc | 39 +++++++++++--------------- Calculator/Calculator.h | 10 ++++--- Parser/Parser.cc | 10 +++---- Parser/Parser.h | 11 +++++--- project.cc | 6 ++-- project.h | 6 ++-- test/project_test.cc | 7 +++-- types/.CustomStack.h.swp | Bin 0 -> 12288 bytes types/CustomStack.h | 58 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 104 insertions(+), 44 deletions(-) create mode 100644 types/.CustomStack.h.swp create mode 100644 types/CustomStack.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ea29a31..16cdba8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) include_directories("Calculator") include_directories("Parser") +include_directories("types") set(SOURCES project.cc Calculator/Calculator.cc Parser/Parser.cc) add_library(ProjectLib ${SOURCES}) diff --git a/Calculator/Calculator.cc b/Calculator/Calculator.cc index b08b533..a1df57f 100644 --- a/Calculator/Calculator.cc +++ b/Calculator/Calculator.cc @@ -1,12 +1,13 @@ #include "Calculator.h" +#include namespace { const auto kError = std::numeric_limits::min(); } namespace dev { - Calculator::Calculator(std::unique_ptr> numbers, - std::unique_ptr> operators) + Calculator::Calculator(NumbersStackPtr numbers, + OperatorsListPtr operators) : numbers_(std::move(numbers)) , operators_(std::move(operators)) { } @@ -21,38 +22,30 @@ int Calculator::calculate() { // This will prevent double using of numbers_->pop_back() for(const auto& math_operator : *operators_) { if (math_operator == "+") { - auto left_op = (*numbers_)[numbers_->size() - 1]; - auto right_op = (*numbers_)[numbers_->size() - 2]; - numbers_->pop_back(); - numbers_->pop_back(); - numbers_->push_back(add(left_op,right_op)); + auto left = numbers_->pop(); + auto right = numbers_->pop(); + numbers_->push(add(left,right)); } if (math_operator == "-") { - auto left_op = (*numbers_)[numbers_->size() - 1]; - auto right_op = (*numbers_)[numbers_->size() - 2]; - numbers_->pop_back(); - numbers_->pop_back(); - numbers_->push_back(dec(left_op,right_op)); + auto left = numbers_->pop(); + auto right = numbers_->pop(); + numbers_->push(dec(left,right)); } if (math_operator == "*") { - auto left_op = (*numbers_)[numbers_->size() - 1]; - auto right_op = (*numbers_)[numbers_->size() - 2]; - numbers_->pop_back(); - numbers_->pop_back(); - numbers_->push_back(mul(left_op,right_op)); + auto left = numbers_->pop(); + auto right = numbers_->pop(); + numbers_->push(mul(left,right)); } if (math_operator == "/") { - auto left_op = (*numbers_)[numbers_->size() - 1]; - auto right_op = (*numbers_)[numbers_->size() - 2]; - numbers_->pop_back(); - numbers_->pop_back(); - numbers_->push_back(div(left_op,right_op)); + auto left = numbers_->pop(); + auto right = numbers_->pop(); + numbers_->push(div(left,right)); } } - return *numbers_->begin(); + return numbers_->top(); } int Calculator::add(int first, int second) { diff --git a/Calculator/Calculator.h b/Calculator/Calculator.h index e436110..c425016 100644 --- a/Calculator/Calculator.h +++ b/Calculator/Calculator.h @@ -2,6 +2,7 @@ #define CALCULATOR_CALCULATOR_H #include "ICalculator.h" +#include "CustomStack.h" #include #include @@ -10,10 +11,11 @@ namespace dev { + using namespace types; + class Calculator : public ICalculator { public: - Calculator(std::unique_ptr> numbers, - std::unique_ptr> operators); + Calculator(NumbersStackPtr numbers, OperatorsListPtr operators); int calculate() override; private: @@ -22,8 +24,8 @@ namespace dev { int dec(int first, int second); int mul(int first, int second); - std::unique_ptr> numbers_; - std::unique_ptr> operators_; + NumbersStackPtr numbers_; + OperatorsListPtr operators_; }; } diff --git a/Parser/Parser.cc b/Parser/Parser.cc index b7ece1f..ddf7e7f 100644 --- a/Parser/Parser.cc +++ b/Parser/Parser.cc @@ -6,8 +6,8 @@ namespace { namespace dev { Parser::Parser() - : numbers_(new std::vector()), - operators_(new std::vector()) { + : numbers_(new NumbersStack()), + operators_(new OperatorsList()) { } bool Parser::parse(const std::string& data) { @@ -28,7 +28,7 @@ bool Parser::parse(const std::string& data) { try { int number = std::stoi(buffer); - numbers_->push_back(number); + numbers_->push(number); } catch (const std::exception& exception) { // KEK @@ -55,11 +55,11 @@ std::string Parser::string_matches_operator(const std::string& possible_operator return possible_operator; } -std::unique_ptr> Parser::get_numbers() { +NumbersStackPtr Parser::get_numbers() { return std::move(numbers_); } -std::unique_ptr> Parser::get_operators() { +OperatorsListPtr Parser::get_operators() { return std::move(operators_); } diff --git a/Parser/Parser.h b/Parser/Parser.h index 7ee030a..c5a426f 100644 --- a/Parser/Parser.h +++ b/Parser/Parser.h @@ -2,6 +2,7 @@ #define PARSER_PARSER_H #include "IParser.h" +#include "CustomStack.h" #include #include @@ -13,18 +14,20 @@ namespace dev { + using namespace types; + class Parser : public IParser { public: Parser(); bool parse(const std::string& data) override; - std::unique_ptr> get_numbers(); - std::unique_ptr> get_operators(); + NumbersStackPtr get_numbers(); + OperatorsListPtr get_operators(); private: std::string string_matches_operator(const std::string& possible_operator); - std::unique_ptr> numbers_; - std::unique_ptr> operators_; + NumbersStackPtr numbers_; + OperatorsListPtr operators_; }; } diff --git a/project.cc b/project.cc index 02f165c..a20a9a9 100644 --- a/project.cc +++ b/project.cc @@ -33,11 +33,11 @@ int Project::calculate() { return calculator_->calculate(); } -std::vector Project::get_numbers() { - return *parser_->get_numbers(); +std::stack Project::get_numbers() { + return parser_->get_numbers()->get_stack(); } -std::vector Project::get_operators() { +OperatorsList Project::get_operators() { return *parser_->get_operators(); } diff --git a/project.h b/project.h index 7aeb426..b709618 100644 --- a/project.h +++ b/project.h @@ -9,6 +9,7 @@ #include #include #include +#include "CustomStack.h" namespace dev { @@ -20,9 +21,8 @@ class Project : public IProject { bool parse_string(const std::string& data); int calculate(); - - std::vector get_numbers(); - std::vector get_operators(); + std::stack get_numbers(); + OperatorsList get_operators(); private: std::unique_ptr calculator_; diff --git a/test/project_test.cc b/test/project_test.cc index 07c02d5..dff219e 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -25,8 +25,11 @@ TEST_F(ProjectTest, ParseString_FAILURE) { TEST_F(ProjectTest, ParseString_SUCCESS) { EXPECT_TRUE(project_.parse_string("5 5 +")); - std::vector expected_numbers = {5,5}; - std::vector expected_operators = {"+"}; + std::stack expected_numbers; + for(const auto& number : {5,5}) { + expected_numbers.push(number); + } + OperatorsList expected_operators = {"+"}; EXPECT_EQ(expected_numbers, project_.get_numbers()); EXPECT_EQ(expected_operators, project_.get_operators()); } diff --git a/types/.CustomStack.h.swp b/types/.CustomStack.h.swp new file mode 100644 index 0000000000000000000000000000000000000000..5bd369b3955462c46070d2312c4fd7d195695a1c GIT binary patch literal 12288 zcmeI2y>HV%7>BP+2wJ|nB6KBEn+*M+fIuNcf(ikG(n@iW5Fq2&m&V{P>~mfDDiU zGC&5%02$cQ2Bg=+7E!^rq>5s)@9Eelr?evjWPl8i0Wv@a$N(8217v^ab3^!NYLZpJ=>58yp`0Um=#U=b_;6I8%iupfNg#n^N34BQ8Ga094d z3KT#;_}$0YPw)eL0dK)8@Dkhu7BGMgCczlUgCWohzV|Zr4J?7r;2n4ho`8qo0cZgY zTmx6Z0q_eoz5y*T58|4);60-$lL0b72FL&zAOmE83~Vg}IpG*)jkOr((YLRLsPRA= z#bN_r!@7PcJ`SXBIwZ%HZR3M^f~ex0>F8EyV3;jz*Kd|HE$!z!+Y +#include +#include + +namespace types { + + template + class CustomStack { + public: + explicit CustomStack() = default; + explicit CustomStack(const CustomStack& ) = default; + explicit CustomStack(CustomStack&&) = default; + + void push(T value) { + stack_.push(value); + } + + T pop() { + T top_element = stack_.top(); + stack_.pop(); + return top_element; + } + + size_t size() const { + return stack_.size(); + } + + std::stack get_stack() const { + return stack_; + } + + T top() const { + return stack_.top(); + } + + bool empty() const { + return stack_.empty(); + } + + void clear() { + while(!empty()) { + stack_.pop(); + } + } + + private: + std::stack stack_; + }; + + typedef std::unique_ptr> NumbersStackPtr; + typedef CustomStack NumbersStack; + typedef std::unique_ptr> OperatorsListPtr; + typedef std::vector OperatorsList; +} +#endif From 5e3bbe41dd9844b8585103a0e27352b501a6a5ad Mon Sep 17 00:00:00 2001 From: KEK Date: Tue, 17 Dec 2019 12:42:39 +0200 Subject: [PATCH 09/25] Add handling of stoi exception --- Parser/Parser.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Parser/Parser.cc b/Parser/Parser.cc index ddf7e7f..db83247 100644 --- a/Parser/Parser.cc +++ b/Parser/Parser.cc @@ -24,16 +24,14 @@ bool Parser::parse(const std::string& data) { std::string math_operator = string_matches_operator(buffer); if (!math_operator.empty()) { operators_->push_back(math_operator); + continue; } try { int number = std::stoi(buffer); numbers_->push(number); } catch (const std::exception& exception) { - // KEK - - // TODO: Figure out how to handle this exception - // (if it should be) + std::cerr << "cannot convert "<< buffer << " to number!" << std::endl; } } From afd648b5b774924470ffd348a2d30e968d8ccb46 Mon Sep 17 00:00:00 2001 From: KEK Date: Tue, 17 Dec 2019 13:23:11 +0200 Subject: [PATCH 10/25] Remove obsolete methods from class Project --- project.cc | 8 -------- project.h | 3 --- test/project_test.cc | 7 ------- 3 files changed, 18 deletions(-) diff --git a/project.cc b/project.cc index a20a9a9..765f084 100644 --- a/project.cc +++ b/project.cc @@ -33,12 +33,4 @@ int Project::calculate() { return calculator_->calculate(); } -std::stack Project::get_numbers() { - return parser_->get_numbers()->get_stack(); -} - -OperatorsList Project::get_operators() { - return *parser_->get_operators(); -} - } // namespace dev diff --git a/project.h b/project.h index b709618..9f4684e 100644 --- a/project.h +++ b/project.h @@ -21,9 +21,6 @@ class Project : public IProject { bool parse_string(const std::string& data); int calculate(); - std::stack get_numbers(); - OperatorsList get_operators(); - private: std::unique_ptr calculator_; std::unique_ptr parser_; diff --git a/test/project_test.cc b/test/project_test.cc index dff219e..7a1dae2 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -25,13 +25,6 @@ TEST_F(ProjectTest, ParseString_FAILURE) { TEST_F(ProjectTest, ParseString_SUCCESS) { EXPECT_TRUE(project_.parse_string("5 5 +")); - std::stack expected_numbers; - for(const auto& number : {5,5}) { - expected_numbers.push(number); - } - OperatorsList expected_operators = {"+"}; - EXPECT_EQ(expected_numbers, project_.get_numbers()); - EXPECT_EQ(expected_operators, project_.get_operators()); } TEST_F(ProjectTest, CalculateNothing) { From fc1e499748585afa678c687f9035f477dbf0d951 Mon Sep 17 00:00:00 2001 From: KEK Date: Tue, 17 Dec 2019 13:39:37 +0200 Subject: [PATCH 11/25] Leave only run method in project and adjust tests --- project.cc | 21 +++++---------------- project.h | 2 -- test/project_test.cc | 40 +++++++++++++++------------------------- 3 files changed, 20 insertions(+), 43 deletions(-) diff --git a/project.cc b/project.cc index 765f084..e06a60c 100644 --- a/project.cc +++ b/project.cc @@ -7,27 +7,16 @@ namespace { } // TODO: Project must use separate objects for calculate() and parse_string() options -Project::Project() : parser_(new Parser()){ - +Project::Project() { } int Project::run(const std::string& user_input) { - return parse_string(user_input) ? - calculate() - : - kError; -} - -// TODO: Move this method to separate object. -bool Project::parse_string(const std::string& data) { - if (!parser_) { - return false; + parser_.reset(new Parser()); + const bool parsing_successful = parser_->parse(user_input); + if (!parsing_successful) { + return kError; } - return parser_->parse(data); -} -// TODO: Move this method to separate object. -int Project::calculate() { calculator_.reset(new Calculator(parser_->get_numbers(), parser_->get_operators())); return calculator_->calculate(); diff --git a/project.h b/project.h index 9f4684e..0a06995 100644 --- a/project.h +++ b/project.h @@ -18,8 +18,6 @@ class Project : public IProject { public: Project(); int run(const std::string& user_input); - bool parse_string(const std::string& data); - int calculate(); private: std::unique_ptr calculator_; diff --git a/test/project_test.cc b/test/project_test.cc index 7a1dae2..1b37054 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -18,67 +18,57 @@ class ProjectTest : public ::testing::Test { }; TEST_F(ProjectTest, ParseString_FAILURE) { - EXPECT_FALSE(project_.parse_string("")); - EXPECT_FALSE(project_.parse_string(" 5 4 3 2 ")); - EXPECT_FALSE(project_.parse_string(" + - = * ")); + EXPECT_EQ(kError, project_.run("")); + EXPECT_EQ(kError, project_.run(" 5 4 3 2 ")); + EXPECT_EQ(kError, project_.run(" + - = * ")); } TEST_F(ProjectTest, ParseString_SUCCESS) { - EXPECT_TRUE(project_.parse_string("5 5 +")); + EXPECT_TRUE(project_.run("5 5 +")); } TEST_F(ProjectTest, CalculateNothing) { - ASSERT_EQ(kError, project_.calculate()); + EXPECT_EQ(kError, project_.run("")); } TEST_F(ProjectTest, CalculateNoOperators) { - ASSERT_FALSE(project_.parse_string("5 5")); - EXPECT_EQ(kError, project_.calculate()); + EXPECT_EQ(kError, project_.run("5 5")); } TEST_F(ProjectTest, CalculateNoNumbers) { - ASSERT_FALSE(project_.parse_string("+ - / *")); - EXPECT_EQ(kError, project_.calculate()); + EXPECT_EQ(kError, project_.run("+ - / *")); } TEST_F(ProjectTest, CalculateAdd) { - ASSERT_TRUE(project_.parse_string("5 5 +")); - EXPECT_EQ(10, project_.calculate()); + EXPECT_EQ(10, project_.run("5 5 +")); } TEST_F(ProjectTest, CalculateDecrease) { - ASSERT_TRUE(project_.parse_string("7 5 -")); - EXPECT_EQ(-2, project_.calculate()); + EXPECT_EQ(-2, project_.run("7 5 -")); } TEST_F(ProjectTest, CalculateMultiply) { - ASSERT_TRUE(project_.parse_string("5 7 *")); - EXPECT_EQ(35, project_.calculate()); + EXPECT_EQ(35, project_.run("5 7 *")); } TEST_F(ProjectTest, CalculateDivide) { - ASSERT_TRUE(project_.parse_string("7 14 /")); - EXPECT_EQ(2, project_.calculate()); + EXPECT_EQ(2, project_.run("7 14 /")); } TEST_F(ProjectTest, CalculateAddMultiple) { - ASSERT_TRUE(project_.parse_string("14 7 3 4 + + +")); - EXPECT_EQ(28, project_.calculate()); + EXPECT_EQ(28, project_.run("14 7 3 4 + + +")); } TEST_F(ProjectTest, CalculateSeveralOperations) { - ASSERT_TRUE(project_.parse_string("4 4 4 4 + * -")); - EXPECT_EQ(28, project_.calculate()); + EXPECT_EQ(28, project_.run("4 4 4 4 + * -")); } TEST_F(ProjectTest, CalculateSeveralOperationsDifferentPlacementOrder) { - ASSERT_TRUE(project_.parse_string("1 2 + 4 * 3 +")); - EXPECT_EQ(15, project_.calculate()); + EXPECT_EQ(15, project_.run("1 2 + 4 * 3 +")); } TEST_F(ProjectTest, CalculateDividingZero) { - ASSERT_TRUE(project_.parse_string("0 1 /")); - EXPECT_EQ(kError, project_.calculate()); + EXPECT_EQ(kError, project_.run("0 1 /")); } } // namespace testing From 8b624cea5a1c1c1dfc95191fb14617bb5a69107a Mon Sep 17 00:00:00 2001 From: KEK Date: Tue, 17 Dec 2019 13:40:31 +0200 Subject: [PATCH 12/25] fixup! Leave only run method in project and adjust tests --- project.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/project.cc b/project.cc index e06a60c..1739de6 100644 --- a/project.cc +++ b/project.cc @@ -6,7 +6,6 @@ namespace { const auto kError = std::numeric_limits::min(); } -// TODO: Project must use separate objects for calculate() and parse_string() options Project::Project() { } From b3dc11373ea5415a131eb75b197c8a54eaa0ce94 Mon Sep 17 00:00:00 2001 From: KEK Date: Tue, 17 Dec 2019 13:41:17 +0200 Subject: [PATCH 13/25] Remove useless comment --- project.h | 1 - 1 file changed, 1 deletion(-) diff --git a/project.h b/project.h index 0a06995..e045358 100644 --- a/project.h +++ b/project.h @@ -14,7 +14,6 @@ namespace dev { class Project : public IProject { - // IProject interface public: Project(); int run(const std::string& user_input); From f10bc8f4e6719319ce9b00b38f0e7bd7e70492ae Mon Sep 17 00:00:00 2001 From: KEK Date: Tue, 17 Dec 2019 13:53:49 +0200 Subject: [PATCH 14/25] Enhance calculate method operators processing --- Calculator/Calculator.cc | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Calculator/Calculator.cc b/Calculator/Calculator.cc index a1df57f..2bc40aa 100644 --- a/Calculator/Calculator.cc +++ b/Calculator/Calculator.cc @@ -17,32 +17,27 @@ int Calculator::calculate() { return kError; } - // TODO: Redefine numbers_ as custom stack - // with overrided 'pop' method. - // This will prevent double using of numbers_->pop_back() for(const auto& math_operator : *operators_) { + auto left = numbers_->pop(); + auto right = numbers_->pop(); if (math_operator == "+") { - auto left = numbers_->pop(); - auto right = numbers_->pop(); numbers_->push(add(left,right)); + continue; } if (math_operator == "-") { - auto left = numbers_->pop(); - auto right = numbers_->pop(); numbers_->push(dec(left,right)); + continue; } if (math_operator == "*") { - auto left = numbers_->pop(); - auto right = numbers_->pop(); numbers_->push(mul(left,right)); + continue; } if (math_operator == "/") { - auto left = numbers_->pop(); - auto right = numbers_->pop(); numbers_->push(div(left,right)); + continue; } } return numbers_->top(); From 69297adf5901da25b7ed930ffc983764b3a99070 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 11:55:11 +0200 Subject: [PATCH 15/25] Add constructor from initializer_list to CustomStack --- types/CustomStack.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/types/CustomStack.h b/types/CustomStack.h index ac71bc6..87af387 100644 --- a/types/CustomStack.h +++ b/types/CustomStack.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace types { @@ -13,6 +14,11 @@ namespace types { explicit CustomStack() = default; explicit CustomStack(const CustomStack& ) = default; explicit CustomStack(CustomStack&&) = default; + explicit CustomStack(const std::initializer_list& list) { + for (const auto& element : list) { + stack_.push(element); + } + } void push(T value) { stack_.push(value); From 33002eea38d468e3aaeeca5d3adec1f5a6be17d9 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 11:55:46 +0200 Subject: [PATCH 16/25] Remove obsolete methods from IProject interface --- iproject.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/iproject.h b/iproject.h index 429a664..e926412 100644 --- a/iproject.h +++ b/iproject.h @@ -5,8 +5,6 @@ namespace dev{ class IProject { virtual int run(const std::string& user_input) = 0; - virtual bool parse_string(const std::string& data) = 0; - virtual int calculate() = 0; }; } From 4c00264f399d93e25091c573a23d197402138c3b Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 11:58:29 +0200 Subject: [PATCH 17/25] Add unit tests for Calculator and make some cleanup --- Calculator/Calculator.cc | 2 +- test/CMakeLists.txt | 5 +++ test/calculator_test.cc | 71 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 test/calculator_test.cc diff --git a/Calculator/Calculator.cc b/Calculator/Calculator.cc index 2bc40aa..f8c9e25 100644 --- a/Calculator/Calculator.cc +++ b/Calculator/Calculator.cc @@ -48,7 +48,7 @@ int Calculator::add(int first, int second) { } int Calculator::div(int first, int second) { - return second ? first / second : kError; + return second ? (first / second) : kError; } int Calculator::dec(int first, int second) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8d6190d..4511379 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,5 +3,10 @@ include_directories (${CMAKE_SOURCE_DIR}) include(AddGoogleTest) add_executable (ProjectTest project_test.cc) +add_executable (CalculatorTest calculator_test.cc) +# add_executable (ParserTest parser_test.cc) add_gtest(ProjectTest) +add_gtest(CalculatorTest) +# add_gtest(ParserTest) target_link_libraries(ProjectTest PUBLIC ProjectLib) +target_link_libraries(CalculatorTest PUBLIC ProjectLib) diff --git a/test/calculator_test.cc b/test/calculator_test.cc new file mode 100644 index 0000000..71757cd --- /dev/null +++ b/test/calculator_test.cc @@ -0,0 +1,71 @@ +#include "Calculator.h" +#include +#include +namespace dev { +namespace testing { + +namespace { + const auto kError = std::numeric_limits::min(); +} + +class CalculatorTest : public ::testing::Test { + public: + void SetUp() override { + } + void TearDown() override { + numbers_.reset(); + operators_.reset(); + } + + void PrepareTest(const std::initializer_list& numbers, + const std::initializer_list& operators) { + numbers_.reset(new NumbersStack(numbers)); + operators_.reset(new OperatorsList(operators)); + calculator_.reset(new Calculator(std::move(numbers_), + std::move(operators_))); + } + std::unique_ptr calculator_; + NumbersStackPtr numbers_; + OperatorsListPtr operators_; +}; + +TEST_F(CalculatorTest, CalculateAdd) { + PrepareTest({10,20},{"+"}); + EXPECT_EQ(30,calculator_->calculate()); +} +TEST_F(CalculatorTest, CalculateDecrease) { + PrepareTest({10,20},{"-"}); + EXPECT_EQ(10,calculator_->calculate()); +} +TEST_F(CalculatorTest, CalculateMultiply) { + PrepareTest({10,20},{"*"}); + EXPECT_EQ(200,calculator_->calculate()); +} +TEST_F(CalculatorTest, CalculateDiv) { + PrepareTest({10,20},{"/"}); + EXPECT_EQ(2,calculator_->calculate()); +} +TEST_F(CalculatorTest, CalculateComplex) { + PrepareTest({10,20,30,40,80},{"+","*","-","/"}); + EXPECT_EQ(358,calculator_->calculate()); +} + +TEST_F(CalculatorTest, CalculateNoNumbers) { + PrepareTest({},{"+","*","-","/"}); + EXPECT_EQ(kError,calculator_->calculate()); +} +TEST_F(CalculatorTest, CalculateNoOperators) { + PrepareTest({10,20},{}); + EXPECT_EQ(kError,calculator_->calculate()); +} +TEST_F(CalculatorTest, CalculateNothing) { + PrepareTest({},{}); + EXPECT_EQ(kError,calculator_->calculate()); +} +TEST_F(CalculatorTest, CalculateDivideZero) { + PrepareTest({0,1},{"/"}); + EXPECT_EQ(kError,calculator_->calculate()); +} + +} // namespace testing +} // namespace dev From 8894cae2d0e7b9ef397c47c437f7bbc8446e5b56 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 11:58:45 +0200 Subject: [PATCH 18/25] Update vim settings --- .vimrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vimrc b/.vimrc index d1d53ee..062dfa5 100644 --- a/.vimrc +++ b/.vimrc @@ -25,7 +25,8 @@ command! Run :call Run() function! Test() silent :!clear - silent :!cd build/test && ./ProjectTest + silent :!cd build/test && ./ProjectTest; + silent :!cd build/test && ./CalculatorTest; :!echo "Done" redraw! endfunction From 9c18cbf68d69fff6b07db86440c909c5fb7370a1 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 12:21:37 +0200 Subject: [PATCH 19/25] Add unit tests to Parser. Enhance parse method functionality Add unit tests straight for parse method --- Parser/Parser.cc | 7 ++----- test/CMakeLists.txt | 5 +++-- test/parser_test.cc | 47 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 test/parser_test.cc diff --git a/Parser/Parser.cc b/Parser/Parser.cc index db83247..f913a0b 100644 --- a/Parser/Parser.cc +++ b/Parser/Parser.cc @@ -15,9 +15,6 @@ bool Parser::parse(const std::string& data) { return false; } - numbers_->clear(); - operators_->clear(); - std::istringstream data_stream(data); std::string buffer; while (std::getline(data_stream, buffer, ' ')) { @@ -35,8 +32,8 @@ bool Parser::parse(const std::string& data) { } } - if (numbers_->empty() || operators_->empty()) { - return false; + if (operators_->size() != numbers_->size() - 1) { + return false; } return true; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4511379..90aea53 100755 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,9 +4,10 @@ include(AddGoogleTest) add_executable (ProjectTest project_test.cc) add_executable (CalculatorTest calculator_test.cc) -# add_executable (ParserTest parser_test.cc) +add_executable (ParserTest parser_test.cc) add_gtest(ProjectTest) add_gtest(CalculatorTest) -# add_gtest(ParserTest) +add_gtest(ParserTest) target_link_libraries(ProjectTest PUBLIC ProjectLib) target_link_libraries(CalculatorTest PUBLIC ProjectLib) +target_link_libraries(ParserTest PUBLIC ProjectLib) diff --git a/test/parser_test.cc b/test/parser_test.cc new file mode 100644 index 0000000..9f246de --- /dev/null +++ b/test/parser_test.cc @@ -0,0 +1,47 @@ +#include "Parser.h" +#include +#include + +namespace dev { +namespace testing { + +namespace { + const auto kError = std::numeric_limits::min(); +} + +class ParserTest : public ::testing::Test { + protected: + dev::Parser parser_; +}; + +TEST_F(ParserTest, ParseString_Add) { + EXPECT_TRUE(parser_.parse("5 5 +")); +} +TEST_F(ParserTest, ParseString_Dec) { + EXPECT_TRUE(parser_.parse("5 5 -")); +} +TEST_F(ParserTest, ParseString_Div) { + EXPECT_TRUE(parser_.parse("5 5 /")); +} +TEST_F(ParserTest, ParseString_Mul) { + EXPECT_TRUE(parser_.parse("5 5 *")); +} +TEST_F(ParserTest, ParseString_Complex) { + EXPECT_TRUE(parser_.parse("5 5 4 3 * - +")); +} + +TEST_F(ParserTest, ParseString_ComplexFAIL) { + EXPECT_FALSE(parser_.parse("5 5 4 3 * - + *")); +} +TEST_F(ParserTest, ParseString_ParseNothing) { + EXPECT_FALSE(parser_.parse("")); +} +TEST_F(ParserTest, ParseString_ParseNumbersOnly) { + EXPECT_FALSE(parser_.parse(" 5 4 3 2 ")); +} +TEST_F(ParserTest, ParseString_ParseOperatorsOnly) { + EXPECT_FALSE(parser_.parse(" + - = * ")); +} + +} // namespace testing +} // namespace dev From e53a86af267731dad08dc692543edc0e2101ce9a Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 12:22:00 +0200 Subject: [PATCH 20/25] Update vim settings for parser --- .vimrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.vimrc b/.vimrc index 062dfa5..b7549e3 100644 --- a/.vimrc +++ b/.vimrc @@ -27,6 +27,7 @@ function! Test() silent :!clear silent :!cd build/test && ./ProjectTest; silent :!cd build/test && ./CalculatorTest; + silent :!cd build/test && ./ParserTest; :!echo "Done" redraw! endfunction From 5849b586370f2db8421eda4378523bf7535aca85 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 12:24:02 +0200 Subject: [PATCH 21/25] Delete trash files --- Calculator/.Calculator.cc.swp | Bin 12288 -> 0 bytes Calculator/.Calculator.h.swp | Bin 12288 -> 0 bytes Parser/.Calculator.cc.swp | Bin 12288 -> 0 bytes Parser/.Calculator.h.swp | Bin 12288 -> 0 bytes Parser/.IParser.h.swp | Bin 12288 -> 0 bytes Parser/.Parser.cc.swp | Bin 12288 -> 0 bytes Parser/.Parser.h.swp | Bin 12288 -> 0 bytes types/.CustomStack.h.swp | Bin 12288 -> 0 bytes 8 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Calculator/.Calculator.cc.swp delete mode 100644 Calculator/.Calculator.h.swp delete mode 100644 Parser/.Calculator.cc.swp delete mode 100644 Parser/.Calculator.h.swp delete mode 100644 Parser/.IParser.h.swp delete mode 100644 Parser/.Parser.cc.swp delete mode 100644 Parser/.Parser.h.swp delete mode 100644 types/.CustomStack.h.swp diff --git a/Calculator/.Calculator.cc.swp b/Calculator/.Calculator.cc.swp deleted file mode 100644 index d635c7ac465f79f71e75f62cd05364555bb73a46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2&5zqe7>B1wAifF+Zd8@trcxX4#>wtd3QD`nq2}IX}pC zc2<~ z18jf|uz@?!KoAM>`#nM|-ize%|NrUl|34nab?_7T5_|zZ2Uo%K;BN5SLqdEFz5<_t zPeBOQ!E@j=*blDl6=Dl~2vTqq{QIB~zk(mYC*TVB0L0)3xb}b$zku(-Rd5-+56*%W z@X!51{0zPYAA$G4yI>5Kz~A>Fcd!MnfOo*#U<4u%f}>zR*asd5f5O3c;2W?7J_hH( zCYXRzU3l0XDz}*Z>>YRR%6JO^6GENJ~@dltxMyh8C!hVU|Y6gh~xH zZ}Ro~Ng228wW?o->}lQAqqlAn$lozgB*Xav)#2$Gms-z7q&}T{R_jdvKgUQ-<_ld< zc5%lXgD9FW&_Y@!L#c~_zc!Q`Ds6kmpww!e{v~R<t0ZrjHcmemD;oPyw{qTg?dxAJ@RSgj7`?IYM{&K_T!e_I5nbn z5|}Y^m)gGXNvo^W>b0sT!iKFqTsNPY0sB1dQUeR~8L$gsmm2WrGhmn5E;X=N86X;E zx{ZR0(rVY(A-aCO^l4$bc8Y;rHblK1y*yS0ZK^n?T+4|>rH!(37)vS(m2OZrx@m!^ z$8IV!rfed$R*{V8aGvFdDUoKJMO_zt{p5O|UXqa^Yc7^FxzWd~&l9|?p1JeFXsBIVYf|v+M7M8%&3XNu zJA}hT5ys`xA&~}&Eb<_f6v@eSt8AVKx0j*lRykpu)G8drDp965Zi7KXy{|NpAnc$@ P!?=tjwVJ%T?LISE881)#MRbiLODhB{ld4M zRr*AoCQ;}fyG)rpGO?6-OIIdl5j`yvm!*rMgI;QqJr&sHjvodt^lf4)&DQQ;CgU(0 zU<1<|aCWeCZJsV&TwTcr)oTml%;~M^$8#ndU;}J`4X^<=zy{a=8(;%7Z@{K=^bDss zR-WX1S<~18jf|umLu}2G{@_U;{H~z?VdCj}zUT$L8_>|M>U+ zmy<;A!8`B>&uME^xEcJlskc2qAjz?ZHD?QJ}df%yDYRy{l zKE##hq-Z{5KD%KPTipYhHydG$i*=Es|sUV5v z;&}QzDpfE|mL5)#ZuPTjfz@mqB^&TQwF%GE~NBsmA*oouzpGgT#7OyL F{0I676V3nt diff --git a/Parser/.Calculator.cc.swp b/Parser/.Calculator.cc.swp deleted file mode 100644 index 2458b9184406fd254235a1ff4934524d341e146a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 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 YNNZ{;VM`qoksD+lr%ut;qTgZv0K`kNlmGw# diff --git a/Parser/.Parser.h.swp b/Parser/.Parser.h.swp deleted file mode 100644 index 2568d85fd28b8409c1f038bd23ab78ecfc892ade..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2O=}ZD7{{M@wkrAo9J3;g*tFV~mb3(<2-X)U6}?DV_GQvc*|+Y@hK5o-^fUMs z^r}a_dRLEr0l~B2-T!7MWoe~0Hw(|eFOzv@o|$KU<~18jf|umLu}2G{@_U<2pSfEN;dzDV?P3dQ69|MBzx&&x#L zz*q1Id<5^n8*m7A!4`M~7Qq6z2^`P>zb_H}03X16Fa*nB3ET$Xao$_710)E556U{8 zfX9Fv8(;%$fDNz#Hoykh02^QfY~a5$;K(FYJ;$kfJOowa(I?RX330H3kFseKb~;6( zb_?ldCSM(m2Y3xSwcoYLRkGdfiZqkChp=|flB*JfoTP|-c|4=q5hs@$yRm12zSQn` z`{^J}w5jTo38C1qPkv!sT1)(XaO6I diff --git a/types/.CustomStack.h.swp b/types/.CustomStack.h.swp deleted file mode 100644 index 5bd369b3955462c46070d2312c4fd7d195695a1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2y>HV%7>BP+2wJ|nB6KBEn+*M+fIuNcf(ikG(n@iW5Fq2&m&V{P>~mfDDiU zGC&5%02$cQ2Bg=+7E!^rq>5s)@9Eelr?evjWPl8i0Wv@a$N(8217v^ab3^!NYLZpJ=>58yp`0Um=#U=b_;6I8%iupfNg#n^N34BQ8Ga094d z3KT#;_}$0YPw)eL0dK)8@Dkhu7BGMgCczlUgCWohzV|Zr4J?7r;2n4ho`8qo0cZgY zTmx6Z0q_eoz5y*T58|4);60-$lL0b72FL&zAOmE83~Vg}IpG*)jkOr((YLRLsPRA= z#bN_r!@7PcJ`SXBIwZ%HZR3M^f~ex0>F8EyV3;jz*Kd|HE$!z!+Y Date: Wed, 18 Dec 2019 12:48:31 +0200 Subject: [PATCH 22/25] Add split method to Parser and refactor parse method --- Parser/Parser.cc | 27 ++++++++++++++++++++------- Parser/Parser.h | 5 ++++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Parser/Parser.cc b/Parser/Parser.cc index f913a0b..f31f457 100644 --- a/Parser/Parser.cc +++ b/Parser/Parser.cc @@ -15,20 +15,22 @@ bool Parser::parse(const std::string& data) { return false; } - std::istringstream data_stream(data); - std::string buffer; - while (std::getline(data_stream, buffer, ' ')) { - std::string math_operator = string_matches_operator(buffer); + const auto& splitted_data = split(data); + for (const auto& user_data : splitted_data) { + + // Append operators list + std::string math_operator = string_matches_operator(user_data); if (!math_operator.empty()) { operators_->push_back(math_operator); continue; } + // Append numbers list try { - int number = std::stoi(buffer); + int number = std::stoi(user_data); numbers_->push(number); } catch (const std::exception& exception) { - std::cerr << "cannot convert "<< buffer << " to number!" << std::endl; + std::cerr << "cannot convert "<< user_data << " to number!" << std::endl; } } @@ -39,7 +41,8 @@ bool Parser::parse(const std::string& data) { return true; } -std::string Parser::string_matches_operator(const std::string& possible_operator) { +std::string +Parser::string_matches_operator(const std::string& possible_operator) const { if (possible_operator != "*" && possible_operator != "+" && possible_operator != "-" && @@ -50,6 +53,16 @@ std::string Parser::string_matches_operator(const std::string& possible_operator return possible_operator; } +std::vector Parser::split(const std::string& data) const { + std::istringstream data_stream(data); + std::string buffer; + std::vector result; + while (std::getline(data_stream, buffer, ' ')) { + result.push_back(buffer); + } + return result; +} + NumbersStackPtr Parser::get_numbers() { return std::move(numbers_); } diff --git a/Parser/Parser.h b/Parser/Parser.h index c5a426f..eea126c 100644 --- a/Parser/Parser.h +++ b/Parser/Parser.h @@ -25,7 +25,10 @@ namespace dev { OperatorsListPtr get_operators(); private: - std::string string_matches_operator(const std::string& possible_operator); + std::string + string_matches_operator(const std::string& possible_operator) const; + std::vector + split(const std::string&) const; NumbersStackPtr numbers_; OperatorsListPtr operators_; }; From 93d244532a91ad8a7b1ed41e2daf8bcd25e56aad Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 13:30:25 +0200 Subject: [PATCH 23/25] Migrate to floats --- Calculator/Calculator.cc | 12 ++++++------ Calculator/Calculator.h | 10 +++++----- Calculator/ICalculator.h | 2 +- Parser/Parser.cc | 4 ++-- iproject.h | 2 +- main.cc | 8 ++++---- project.cc | 4 ++-- project.h | 2 +- test/calculator_test.cc | 28 ++++++++++++++-------------- test/parser_test.cc | 2 +- test/project_test.cc | 4 +--- types/CustomStack.h | 4 ++-- 12 files changed, 40 insertions(+), 42 deletions(-) diff --git a/Calculator/Calculator.cc b/Calculator/Calculator.cc index f8c9e25..41d7f01 100644 --- a/Calculator/Calculator.cc +++ b/Calculator/Calculator.cc @@ -2,7 +2,7 @@ #include namespace { - const auto kError = std::numeric_limits::min(); + const auto kError = std::numeric_limits::min(); } namespace dev { @@ -11,7 +11,7 @@ namespace dev { : numbers_(std::move(numbers)) , operators_(std::move(operators)) { } -int Calculator::calculate() { +float Calculator::calculate() { if (operators_->size() != numbers_->size() - 1) { return kError; @@ -43,19 +43,19 @@ int Calculator::calculate() { return numbers_->top(); } -int Calculator::add(int first, int second) { +float Calculator::add(float first, float second) { return first + second; } -int Calculator::div(int first, int second) { +float Calculator::div(float first, float second) { return second ? (first / second) : kError; } -int Calculator::dec(int first, int second) { +float Calculator::dec(float first, float second) { return first - second; } -int Calculator::mul(int first, int second) { +float Calculator::mul(float first, float second) { return first * second; } diff --git a/Calculator/Calculator.h b/Calculator/Calculator.h index c425016..95636a1 100644 --- a/Calculator/Calculator.h +++ b/Calculator/Calculator.h @@ -16,13 +16,13 @@ namespace dev { class Calculator : public ICalculator { public: Calculator(NumbersStackPtr numbers, OperatorsListPtr operators); - int calculate() override; + float calculate() override; private: - int add(int first, int second); - int div(int first, int second); - int dec(int first, int second); - int mul(int first, int second); + float add(float first, float second); + float div(float first, float second); + float dec(float first, float second); + float mul(float first, float second); NumbersStackPtr numbers_; OperatorsListPtr operators_; diff --git a/Calculator/ICalculator.h b/Calculator/ICalculator.h index 3361bf1..2ba5280 100644 --- a/Calculator/ICalculator.h +++ b/Calculator/ICalculator.h @@ -5,7 +5,7 @@ namespace dev { class ICalculator { public: - virtual int calculate() = 0; + virtual float calculate() = 0; }; } diff --git a/Parser/Parser.cc b/Parser/Parser.cc index f31f457..89e9bfc 100644 --- a/Parser/Parser.cc +++ b/Parser/Parser.cc @@ -1,7 +1,7 @@ #include "Parser.h" namespace { - const auto kError = std::numeric_limits::min(); + const auto kError = std::numeric_limits::min(); } namespace dev { @@ -27,7 +27,7 @@ bool Parser::parse(const std::string& data) { // Append numbers list try { - int number = std::stoi(user_data); + float number = std::stof(user_data); numbers_->push(number); } catch (const std::exception& exception) { std::cerr << "cannot convert "<< user_data << " to number!" << std::endl; diff --git a/iproject.h b/iproject.h index e926412..a6f7ecc 100644 --- a/iproject.h +++ b/iproject.h @@ -4,7 +4,7 @@ namespace dev{ class IProject { - virtual int run(const std::string& user_input) = 0; + virtual float run(const std::string& user_input) = 0; }; } diff --git a/main.cc b/main.cc index 2a64549..70cb1dd 100644 --- a/main.cc +++ b/main.cc @@ -14,17 +14,17 @@ std::string handle_input() { return std::string(user_input); } -void handle_output(int result) { - if (result == std::numeric_limits::min()) { +void handle_output(float result) { + if (result == std::numeric_limits::min()) { std::cout << "Error occured while calculating!" << std::endl; } else { - std::cout << (int)result << std::endl; + std::cout << (float)result << std::endl; } } int main() { std::unique_ptr polish_calculator(new dev::Project); - int result = polish_calculator->run(handle_input()); + float result = polish_calculator->run(handle_input()); handle_output(result); return 0; } diff --git a/project.cc b/project.cc index 1739de6..af8a566 100644 --- a/project.cc +++ b/project.cc @@ -3,13 +3,13 @@ namespace dev { namespace { - const auto kError = std::numeric_limits::min(); + const auto kError = std::numeric_limits::min(); } Project::Project() { } -int Project::run(const std::string& user_input) { +float Project::run(const std::string& user_input) { parser_.reset(new Parser()); const bool parsing_successful = parser_->parse(user_input); if (!parsing_successful) { diff --git a/project.h b/project.h index e045358..138096c 100644 --- a/project.h +++ b/project.h @@ -16,7 +16,7 @@ namespace dev { class Project : public IProject { public: Project(); - int run(const std::string& user_input); + float run(const std::string& user_input); private: std::unique_ptr calculator_; diff --git a/test/calculator_test.cc b/test/calculator_test.cc index 71757cd..008ca5f 100644 --- a/test/calculator_test.cc +++ b/test/calculator_test.cc @@ -5,7 +5,7 @@ namespace dev { namespace testing { namespace { - const auto kError = std::numeric_limits::min(); + const auto kError = std::numeric_limits::min(); } class CalculatorTest : public ::testing::Test { @@ -17,7 +17,7 @@ class CalculatorTest : public ::testing::Test { operators_.reset(); } - void PrepareTest(const std::initializer_list& numbers, + void PrepareTest(const std::initializer_list& numbers, const std::initializer_list& operators) { numbers_.reset(new NumbersStack(numbers)); operators_.reset(new OperatorsList(operators)); @@ -30,24 +30,24 @@ class CalculatorTest : public ::testing::Test { }; TEST_F(CalculatorTest, CalculateAdd) { - PrepareTest({10,20},{"+"}); - EXPECT_EQ(30,calculator_->calculate()); + PrepareTest({10.0,20.0},{"+"}); + EXPECT_EQ(30.0,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateDecrease) { - PrepareTest({10,20},{"-"}); - EXPECT_EQ(10,calculator_->calculate()); + PrepareTest({10.0,20.0},{"-"}); + EXPECT_EQ(10.0,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateMultiply) { - PrepareTest({10,20},{"*"}); - EXPECT_EQ(200,calculator_->calculate()); + PrepareTest({10.0,20.0},{"*"}); + EXPECT_EQ(200.0,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateDiv) { - PrepareTest({10,20},{"/"}); - EXPECT_EQ(2,calculator_->calculate()); + PrepareTest({10.0,20.0},{"/"}); + EXPECT_EQ(2.0,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateComplex) { - PrepareTest({10,20,30,40,80},{"+","*","-","/"}); - EXPECT_EQ(358,calculator_->calculate()); + PrepareTest({10.0,20.0,30.0,40.0,80.0},{"+","*","-","/"}); + EXPECT_EQ(358.0,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateNoNumbers) { @@ -55,7 +55,7 @@ TEST_F(CalculatorTest, CalculateNoNumbers) { EXPECT_EQ(kError,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateNoOperators) { - PrepareTest({10,20},{}); + PrepareTest({10.0,20.0},{}); EXPECT_EQ(kError,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateNothing) { @@ -63,7 +63,7 @@ TEST_F(CalculatorTest, CalculateNothing) { EXPECT_EQ(kError,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateDivideZero) { - PrepareTest({0,1},{"/"}); + PrepareTest({0.0,1.0},{"/"}); EXPECT_EQ(kError,calculator_->calculate()); } diff --git a/test/parser_test.cc b/test/parser_test.cc index 9f246de..05be2ec 100644 --- a/test/parser_test.cc +++ b/test/parser_test.cc @@ -6,7 +6,7 @@ namespace dev { namespace testing { namespace { - const auto kError = std::numeric_limits::min(); + const auto kError = std::numeric_limits::min(); } class ParserTest : public ::testing::Test { diff --git a/test/project_test.cc b/test/project_test.cc index 1b37054..662e7b4 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -5,11 +5,9 @@ namespace dev { namespace testing { namespace { - const auto kError = std::numeric_limits::min(); + const auto kError = std::numeric_limits::min(); } -//TODO: Add appropriate tests for each new component (Calculator / Parser) - class ProjectTest : public ::testing::Test { public: void SetUp() override {} diff --git a/types/CustomStack.h b/types/CustomStack.h index 87af387..84fc10c 100644 --- a/types/CustomStack.h +++ b/types/CustomStack.h @@ -56,8 +56,8 @@ namespace types { std::stack stack_; }; - typedef std::unique_ptr> NumbersStackPtr; - typedef CustomStack NumbersStack; + typedef std::unique_ptr> NumbersStackPtr; + typedef CustomStack NumbersStack; typedef std::unique_ptr> OperatorsListPtr; typedef std::vector OperatorsList; } From 6a1d2cf9b41daa9bd47574e8c6bb06837f8af2f5 Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 13:48:06 +0200 Subject: [PATCH 24/25] Separate general types to utils.h --- Calculator/Calculator.cc | 12 ++++-------- Calculator/Calculator.h | 9 ++++----- Parser/Parser.cc | 12 ++++-------- Parser/Parser.h | 9 +++++---- test/calculator_test.cc | 20 ++++++++------------ test/parser_test.cc | 4 ---- types/CustomStack.h | 5 ----- types/utils.h | 17 +++++++++++++++++ 8 files changed, 42 insertions(+), 46 deletions(-) create mode 100644 types/utils.h diff --git a/Calculator/Calculator.cc b/Calculator/Calculator.cc index 41d7f01..f727a2a 100644 --- a/Calculator/Calculator.cc +++ b/Calculator/Calculator.cc @@ -1,20 +1,16 @@ #include "Calculator.h" #include -namespace { - const auto kError = std::numeric_limits::min(); -} - namespace dev { - Calculator::Calculator(NumbersStackPtr numbers, - OperatorsListPtr operators) + Calculator::Calculator(types::NumbersStackPtr numbers, + types::OperatorsListPtr operators) : numbers_(std::move(numbers)) , operators_(std::move(operators)) { } float Calculator::calculate() { if (operators_->size() != numbers_->size() - 1) { - return kError; + return types::kError; } for(const auto& math_operator : *operators_) { @@ -48,7 +44,7 @@ float Calculator::add(float first, float second) { } float Calculator::div(float first, float second) { - return second ? (first / second) : kError; + return second ? (first / second) : types::kError; } float Calculator::dec(float first, float second) { diff --git a/Calculator/Calculator.h b/Calculator/Calculator.h index 95636a1..6a99b27 100644 --- a/Calculator/Calculator.h +++ b/Calculator/Calculator.h @@ -3,6 +3,7 @@ #include "ICalculator.h" #include "CustomStack.h" +#include "utils.h" #include #include @@ -11,11 +12,9 @@ namespace dev { - using namespace types; - class Calculator : public ICalculator { public: - Calculator(NumbersStackPtr numbers, OperatorsListPtr operators); + Calculator(types::NumbersStackPtr numbers, types::OperatorsListPtr operators); float calculate() override; private: @@ -24,8 +23,8 @@ namespace dev { float dec(float first, float second); float mul(float first, float second); - NumbersStackPtr numbers_; - OperatorsListPtr operators_; + types::NumbersStackPtr numbers_; + types::OperatorsListPtr operators_; }; } diff --git a/Parser/Parser.cc b/Parser/Parser.cc index 89e9bfc..2ccc955 100644 --- a/Parser/Parser.cc +++ b/Parser/Parser.cc @@ -1,13 +1,9 @@ #include "Parser.h" -namespace { - const auto kError = std::numeric_limits::min(); -} - namespace dev { Parser::Parser() - : numbers_(new NumbersStack()), - operators_(new OperatorsList()) { + : numbers_(new types::NumbersStack()), + operators_(new types::OperatorsList()) { } bool Parser::parse(const std::string& data) { @@ -63,11 +59,11 @@ std::vector Parser::split(const std::string& data) const { return result; } -NumbersStackPtr Parser::get_numbers() { +types::NumbersStackPtr Parser::get_numbers() { return std::move(numbers_); } -OperatorsListPtr Parser::get_operators() { +types::OperatorsListPtr Parser::get_operators() { return std::move(operators_); } diff --git a/Parser/Parser.h b/Parser/Parser.h index eea126c..3c4937c 100644 --- a/Parser/Parser.h +++ b/Parser/Parser.h @@ -3,6 +3,7 @@ #include "IParser.h" #include "CustomStack.h" +#include "utils.h" #include #include @@ -21,16 +22,16 @@ namespace dev { Parser(); bool parse(const std::string& data) override; - NumbersStackPtr get_numbers(); - OperatorsListPtr get_operators(); + types::NumbersStackPtr get_numbers(); + types::OperatorsListPtr get_operators(); private: std::string string_matches_operator(const std::string& possible_operator) const; std::vector split(const std::string&) const; - NumbersStackPtr numbers_; - OperatorsListPtr operators_; + types::NumbersStackPtr numbers_; + types::OperatorsListPtr operators_; }; } diff --git a/test/calculator_test.cc b/test/calculator_test.cc index 008ca5f..eb01558 100644 --- a/test/calculator_test.cc +++ b/test/calculator_test.cc @@ -4,10 +4,6 @@ namespace dev { namespace testing { -namespace { - const auto kError = std::numeric_limits::min(); -} - class CalculatorTest : public ::testing::Test { public: void SetUp() override { @@ -19,14 +15,14 @@ class CalculatorTest : public ::testing::Test { void PrepareTest(const std::initializer_list& numbers, const std::initializer_list& operators) { - numbers_.reset(new NumbersStack(numbers)); - operators_.reset(new OperatorsList(operators)); + numbers_.reset(new types::NumbersStack(numbers)); + operators_.reset(new types::OperatorsList(operators)); calculator_.reset(new Calculator(std::move(numbers_), std::move(operators_))); } std::unique_ptr calculator_; - NumbersStackPtr numbers_; - OperatorsListPtr operators_; + types::NumbersStackPtr numbers_; + types::OperatorsListPtr operators_; }; TEST_F(CalculatorTest, CalculateAdd) { @@ -52,19 +48,19 @@ TEST_F(CalculatorTest, CalculateComplex) { TEST_F(CalculatorTest, CalculateNoNumbers) { PrepareTest({},{"+","*","-","/"}); - EXPECT_EQ(kError,calculator_->calculate()); + EXPECT_EQ(types::kError,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateNoOperators) { PrepareTest({10.0,20.0},{}); - EXPECT_EQ(kError,calculator_->calculate()); + EXPECT_EQ(types::kError,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateNothing) { PrepareTest({},{}); - EXPECT_EQ(kError,calculator_->calculate()); + EXPECT_EQ(types::kError,calculator_->calculate()); } TEST_F(CalculatorTest, CalculateDivideZero) { PrepareTest({0.0,1.0},{"/"}); - EXPECT_EQ(kError,calculator_->calculate()); + EXPECT_EQ(types::kError,calculator_->calculate()); } } // namespace testing diff --git a/test/parser_test.cc b/test/parser_test.cc index 05be2ec..4fa378c 100644 --- a/test/parser_test.cc +++ b/test/parser_test.cc @@ -5,10 +5,6 @@ namespace dev { namespace testing { -namespace { - const auto kError = std::numeric_limits::min(); -} - class ParserTest : public ::testing::Test { protected: dev::Parser parser_; diff --git a/types/CustomStack.h b/types/CustomStack.h index 84fc10c..026c8c1 100644 --- a/types/CustomStack.h +++ b/types/CustomStack.h @@ -55,10 +55,5 @@ namespace types { private: std::stack stack_; }; - - typedef std::unique_ptr> NumbersStackPtr; - typedef CustomStack NumbersStack; - typedef std::unique_ptr> OperatorsListPtr; - typedef std::vector OperatorsList; } #endif diff --git a/types/utils.h b/types/utils.h new file mode 100644 index 0000000..0f49a45 --- /dev/null +++ b/types/utils.h @@ -0,0 +1,17 @@ +#ifndef UTILS_H +#define UTILS_H + +#include "CustomStack.h" +#include + +namespace types { + + typedef std::unique_ptr> NumbersStackPtr; + typedef CustomStack NumbersStack; + typedef std::unique_ptr> OperatorsListPtr; + typedef std::vector OperatorsList; + + const auto kError = std::numeric_limits::min(); +} + +#endif From 63cccec21c112857f026e741bacf859007f5d44b Mon Sep 17 00:00:00 2001 From: KEK Date: Wed, 18 Dec 2019 14:07:33 +0200 Subject: [PATCH 25/25] Refactor calculator usage --- Calculator/Calculator.cc | 24 ++++++------------------ types/utils.h | 7 +++++++ 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/Calculator/Calculator.cc b/Calculator/Calculator.cc index f727a2a..05b592e 100644 --- a/Calculator/Calculator.cc +++ b/Calculator/Calculator.cc @@ -16,24 +16,12 @@ float Calculator::calculate() { for(const auto& math_operator : *operators_) { auto left = numbers_->pop(); auto right = numbers_->pop(); - if (math_operator == "+") { - numbers_->push(add(left,right)); - continue; - } - - if (math_operator == "-") { - numbers_->push(dec(left,right)); - continue; - } - - if (math_operator == "*") { - numbers_->push(mul(left,right)); - continue; - } - - if (math_operator == "/") { - numbers_->push(div(left,right)); - continue; + switch(*math_operator.begin()) { + case types::Operators::ADD: numbers_->push(add(left,right)); break; + case types::Operators::DEC: numbers_->push(dec(left,right)); break; + case types::Operators::DIV: numbers_->push(div(left,right)); break; + case types::Operators::MUL: numbers_->push(mul(left,right)); break; + default:break; } } return numbers_->top(); diff --git a/types/utils.h b/types/utils.h index 0f49a45..2c77565 100644 --- a/types/utils.h +++ b/types/utils.h @@ -12,6 +12,13 @@ namespace types { typedef std::vector OperatorsList; const auto kError = std::numeric_limits::min(); + + enum Operators : char { + ADD = '+', + DEC = '-', + DIV = '/', + MUL = '*' + }; } #endif