From 98772e0084b1fd65701d6436020e5973e7fd6829 Mon Sep 17 00:00:00 2001 From: Maxim Date: Tue, 17 Dec 2019 10:03:51 +0200 Subject: [PATCH 1/4] Initial commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..92f0e83 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Polish_notation \ No newline at end of file From cc8dfd11f4876fbbd3d4585b8692678d9f154f65 Mon Sep 17 00:00:00 2001 From: Luxuser Date: Tue, 17 Dec 2019 10:06:15 +0200 Subject: [PATCH 2/4] Init commit --- CMakeLists.txt | 5 +- constant.h | 24 +++++++ iproject.h | 3 +- main.cc | 20 +++++- project.cc | 150 ++++++++++++++++++++++++++++++++++++++++- project.cc.autosave | 154 +++++++++++++++++++++++++++++++++++++++++++ project.h | 45 ++++++++++++- test/project_test.cc | 88 ++++++++++++++++++++++++- 8 files changed, 479 insertions(+), 10 deletions(-) create mode 100644 constant.h create mode 100644 project.cc.autosave diff --git a/CMakeLists.txt b/CMakeLists.txt index e6318a3..2717a32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,12 @@ cmake_minimum_required(VERSION 3.5.1) project(dummy_cmake_project) set(CMAKE_CXX_STANDARD 14) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) -set(SOURCES project.cc) +set(SOURCES project.cc constant.h) add_library(ProjectLib ${SOURCES}) add_executable(project main.cc) diff --git a/constant.h b/constant.h new file mode 100644 index 0000000..49433e7 --- /dev/null +++ b/constant.h @@ -0,0 +1,24 @@ +#ifndef CONSTANT +#define CONSTANT + +#include +#include + +namespace polish_notation_constant +{ + typedef double value_t; + typedef std::stack stack_numbers_t; + + constexpr double ERROR_VALUE = std::numeric_limits::max(); + + enum class error_code { + STACK_EMPTY, + NOT_CORRECT_EXPRESSION, + ZERO_DEVISION, + NO_ERROR, + NOT_CORRECT_COUNT_OF_OPERATION + }; +} + +#endif // CONSTANT + diff --git a/iproject.h b/iproject.h index ec4452f..0392514 100644 --- a/iproject.h +++ b/iproject.h @@ -1,9 +1,10 @@ #pragma once +#include namespace dev{ class IProject { - virtual int run() = 0; + virtual double run(std::string) = 0; }; } diff --git a/main.cc b/main.cc index 5b2357f..1029c5a 100644 --- a/main.cc +++ b/main.cc @@ -1,5 +1,21 @@ #include "project.h" +#include "constant.h" +#include +#include -int main() { - return 0; +int main() +{ + dev::Project project; + auto value = project.run("2 3 &"); + + if( value != polish_notation_constant::ERROR_VALUE) + { + std::cout << "Result: " << value << std::endl; + } + else + { + std::cout << "Error code: " << project.get_error_code() << std::endl; + } + + return 0; } diff --git a/project.cc b/project.cc index fdc1225..7287fc2 100644 --- a/project.cc +++ b/project.cc @@ -2,7 +2,153 @@ namespace dev { -int Project::run() { - return 0; + +value_t Project::run(std::string input_str) { + + return processData(input_str); +} + + +bool Project::is_valid_count_value(stack_numbers_t& stack) +{ + if (stack.size() < 2) { + error_code_val = error_code::NOT_CORRECT_COUNT_OF_OPERATION; + + return false; + } + else + { + return true; + } } + +value_t Project::take_value_from_stack(stack_numbers_t& stack) +{ + value_t value = ERROR_VALUE; + + if (stack.size() != 0) { + value = stack.top(); + stack.pop(); + } + else{ + error_code_val = error_code::STACK_EMPTY; + } + + return value; +} + +value_t Project::make_operation(char type_operation, + double left_operand, + double right_operand) +{ + switch(type_operation) { + case '+': + left_operand = sum(left_operand, right_operand); + break; + case '-': + left_operand = subtract(left_operand, right_operand); + break; + case '*': + left_operand = multiplication(left_operand, right_operand); + break; + case '/': + left_operand = division(left_operand, right_operand); + break; + default: + error_code_val = error_code::NOT_CORRECT_EXPRESSION; + break; + } + + return left_operand; +} + +bool Project::is_number(const std::string& s) +{ + char* end = 0; + double val = std::strtod(s.c_str(), &end); + return end != s.c_str() && *end == '\0' && val != HUGE_VAL; +} + +void Project::clear_stack(stack_numbers_t & stack) +{ + while(!stack.empty()) + { + stack.pop(); + } +} + +int Project::get_error_code() +{ + return static_cast(error_code_val); +} + +value_t Project::processData(std::string& input_str) +{ + stack_numbers_t stack_numbers; + error_code_val = error_code::NO_ERROR; + + value_t return_value = ERROR_VALUE; + std::istringstream f(input_str); + std::string temp_str; + + + while (std::getline(f, temp_str, ' ')) { + std::cout << "Stack value: " << temp_str << std::endl; + + if(is_number(temp_str)) { + stack_numbers.push(std::stod(temp_str.c_str())); + } + else { + if (true == is_valid_count_value(stack_numbers)) { + double left_operand, right_operand; + + right_operand = take_value_from_stack(stack_numbers); + left_operand = take_value_from_stack(stack_numbers); + + left_operand = make_operation(temp_str[0], left_operand, right_operand); + stack_numbers.push(left_operand); + } + } + + if(error_code_val != error_code::NO_ERROR) { + clear_stack(stack_numbers); + break; + } + } + + if (stack_numbers.size() != 0) { + return_value = stack_numbers.top(); + } + + return return_value; +} + +double Project::division(double a, double b) +{ + if (b != 0) { + return a / b; + } else { + error_code_val = error_code::ZERO_DEVISION; + + std::cout << "Devision on zero!\n"; + + return -1; + } +} + +double Project::sum(double a, double b) +{ + return a + b; +} + +double Project::subtract(double a, double b) +{ + return a - b; +} + +double Project::multiplication(double a, double b) +{ + return a * b; +} + } // namespace dev diff --git a/project.cc.autosave b/project.cc.autosave new file mode 100644 index 0000000..0c9b6b8 --- /dev/null +++ b/project.cc.autosave @@ -0,0 +1,154 @@ +#include "project.h" + +namespace dev { + + +value_t Project::run(std::string input_str) { + + return processData(input_str); +} + + +bool Project::is_valid_count_value(stack_numbers_t& stack) +{ + if (stack.size() < 2) { + error_code_val = error_code::NOT_CORRECT_COUNT_OF_OPERATION; + + return false; + } + else + { + return true; + } +} + +value_t Project::take_value_from_stack(stack_numbers_t& stack) +{ + value_t value = ERROR_VALUE; + + if (stack.size() != 0) { + value = stack.top(); + stack.pop(); + } + else{ + error_code_val = error_code::STACK_EMPTY; + } + + return value; +} + +value_t Project::make_operation(char type_operation, + double left_operand, + double right_operand) +{ + switch(type_operation) { + case '+': + left_operand = sum(left_operand, right_operand); + break; + case '-': + left_operand = subtract(left_operand, right_operand); + break; + case '*': + left_operand = multiplication(left_operand, right_operand); + break; + case '/': + left_operand = division(left_operand, right_operand); + break; + default: + error_code_val = error_code::NOT_CORRECT_EXPRESSION; + break; + } + + return left_operand; +} + +bool Project::is_number(const std::string& s) +{ + char* end = 0; + double val = std::strtod(s.c_str(), &end); + return end != s.c_str() && *end == '\0' && val != HUGE_VAL; +} + +void Project::clear_stack(stack_numbers_t & stack) +{ + while(!stack.empty()) + { + stack.pop(); + } +} + +int Project::get_error_code() +{ + return static_cast(error_code_val); +} + +value_t Project::processData(std::string& input_str) +{ + stack_numbers_t stack_numbers; + error_code_val = error_code::NO_ERROR; + + value_t return_value = ERROR_VALUE; + std::istringstream f(input_str); + std::string temp_str; + + + while (std::getline(f, temp_str, ' ')) { + std::cout << "Stack value: " << temp_str << std::endl; + + if(is_number(temp_str)) { + stack_numbers.push(std::stod(temp_str.c_str())); + } + else { + if (true == is_valid_count_value(stack_numbers)) { + double left_operand, right_operand; + + right_operand = take_value_from_stack(stack_numbers); + left_operand = take_value_from_stack(stack_numbers); + + left_operand = make_operation(temp_str[0], left_operand, right_operand); + stack_numbers.push(left_operand); + } + } + + if(error_code_val != error_code::NO_ERROR) { + clear_stack(stack_numbers); + break; + } + } + + if (stack_numbers.size() != 0) { + return_value = stack_numbers.top(); + } + + return return_value; +} + +double Project::division(double a, double b) +{ + if (b != 0) { + return a / b; + } else { + error_code_val = error_code::ZERO_DEVISION; + + std::cout << "Devision on zero!\n"; + + return -1; + } +} + +double Project::sum(double a, double b) +{ + return a + b; +} + +double Project::subtract(double a, double b) +{ + return a - b; +} + +double Project::multiplication(double a, double b) +{ + return a * b; +} + +} // namespace dev diff --git a/project.h b/project.h index b5cc813..bd5d131 100644 --- a/project.h +++ b/project.h @@ -1,11 +1,52 @@ #pragma once #include "iproject.h" +#include "constant.h" + +#include +#include +#include +#include +#include +#include + namespace dev { +using namespace polish_notation_constant; + + class Project : public IProject { - // IProject interface + typedef error_code error_t; + + // IProject interface public: - int run(); + double run(std::string); + + // MOve to private section + value_t take_value_from_stack(); + + // MOve to private section + value_t make_operation(char type_operation, + double left_operand, + double right_operand); + + int get_error_code(); + +private: + value_t processData(std::string& input_str); + + bool is_valid_count_value(stack_numbers_t&); + + value_t take_value_from_stack(stack_numbers_t&); + + value_t division (double, double); + value_t sum (double, double); + value_t subtract (double, double); + value_t multiplication (double, double); + + bool is_number(const std::string& s); + + void clear_stack(stack_numbers_t&); + error_t error_code_val = error_code::NO_ERROR; }; } // namespace dev diff --git a/test/project_test.cc b/test/project_test.cc index 5dbeb2f..892dc34 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -1,4 +1,5 @@ #include "project.h" +#include "constant.h" #include #include namespace dev { @@ -11,8 +12,91 @@ class ProjectTest : public ::testing::Test { dev::Project project_; }; -TEST_F(ProjectTest, Run) { - ASSERT_EQ(0, project_.run()); +TEST_F(ProjectTest, Run_int) { + ASSERT_EQ(3, project_.run("1 2 +")); +} + +TEST_F(ProjectTest, Run_double) { + ASSERT_EQ(3.3, project_.run("1.3 2 +")); +} + +TEST_F(ProjectTest, Run_long_expression_below_zero) { + ASSERT_EQ(-1, project_.run("1 2 - 1 + 1 -")); +} + +TEST_F(ProjectTest, Run_long_expression_below_complex_test) { + ASSERT_EQ(21, project_.run("1 2 + 3 4 + *")); +} + +TEST_F(ProjectTest, Run_long_expression_above_zero) { + ASSERT_EQ(49, project_.run("1 2 + 4 + 7 *")); +} + +//TEST_F(ProjectTest, Is_number_double) { +// ASSERT_EQ(true, project_.is_number("1.3")); +//} + +//TEST_F(ProjectTest, Is_number_int) { +// ASSERT_EQ(true, project_.is_number("2")); +//} + +//TEST_F(ProjectTest, Is_number_invalid) { +// ASSERT_EQ(false, project_.is_number("asdas")); +//} + +//TEST_F(ProjectTest, Sum_double) { +// ASSERT_EQ(3.1, project_.sum(1.1, 2)); +//} + +//TEST_F(ProjectTest, Sum_int) { +// ASSERT_EQ(5, project_.sum(2, 3)); +//} + +//TEST_F(ProjectTest, Devision_double) { +// ASSERT_EQ(1.3, project_.division(2.6, 2)); +//} + +//TEST_F(ProjectTest, Devision_int) { +// ASSERT_EQ(3, project_.division(6, 2)); +//} + +//TEST_F(ProjectTest, Devision_zero_devision) { +// ASSERT_EQ(-1, project_.division(6, 0)); +//} + +//TEST_F(ProjectTest, Subtract_int) { +// ASSERT_EQ(4, project_.subtract(6, 2)); +//} + +//TEST_F(ProjectTest, Subtract_double) { +// ASSERT_EQ(4.2, project_.subtract(6.2, 2)); +//} + +//TEST_F(ProjectTest, Multiplication_double) { +// ASSERT_EQ(2.4, project_.multiplication(1.2, 2)); +//} + +//TEST_F(ProjectTest, Multiplication_int) { +// ASSERT_EQ(4, project_.multiplication(2, 2)); +//} + +// to do: test all error code output from project +TEST_F(ProjectTest, Run_error_code_test_NOT_CORRECT_COUNT_OF_OPERATION) { + ASSERT_EQ(polish_notation_constant::ERROR_VALUE, project_.run("+ +")); + ASSERT_EQ(static_cast(polish_notation_constant::error_code::NOT_CORRECT_COUNT_OF_OPERATION), + project_.get_error_code()); +} + +TEST_F(ProjectTest, Run_error_code_test_STACK_EMPTY) { + ASSERT_EQ(polish_notation_constant::ERROR_VALUE, project_.run("")); + ASSERT_EQ(static_cast(polish_notation_constant::error_code::STACK_EMPTY), + project_.get_error_code()); +} + +TEST_F(ProjectTest, Run_error_code_test_STACK_NOT_CORRECT_EXPRESSION) { + ASSERT_EQ(polish_notation_constant::ERROR_VALUE, project_.run("2 * 3")); + ASSERT_EQ(static_cast(polish_notation_constant::error_code::NOT_CORRECT_EXPRESSION), + project_.get_error_code()); } } // namespace testing From 61e7aaeec0829886b0ce76ff231c6fa3e284e375 Mon Sep 17 00:00:00 2001 From: Luxuser Date: Wed, 18 Dec 2019 11:56:48 +0200 Subject: [PATCH 3/4] Add project_operation class --- CMakeLists.txt | 2 +- constant.h | 2 +- main.cc | 2 +- project.cc | 98 +++++++++++---------------- project.cc.autosave | 154 ------------------------------------------ project.h | 25 +++---- project_operation.cpp | 55 +++++++++++++++ project_operation.h | 23 +++++++ test/project_test.cc | 2 +- 9 files changed, 129 insertions(+), 234 deletions(-) delete mode 100644 project.cc.autosave create mode 100644 project_operation.cpp create mode 100644 project_operation.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2717a32..ac1d32d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) -set(SOURCES project.cc constant.h) +set(SOURCES project.cc constant.h project_operation.h project_operation.cpp) add_library(ProjectLib ${SOURCES}) add_executable(project main.cc) diff --git a/constant.h b/constant.h index 49433e7..55b8409 100644 --- a/constant.h +++ b/constant.h @@ -9,7 +9,7 @@ namespace polish_notation_constant typedef double value_t; typedef std::stack stack_numbers_t; - constexpr double ERROR_VALUE = std::numeric_limits::max(); + constexpr value_t ERROR_VALUE = std::numeric_limits::max(); enum class error_code { STACK_EMPTY, diff --git a/main.cc b/main.cc index 1029c5a..d1bf243 100644 --- a/main.cc +++ b/main.cc @@ -6,7 +6,7 @@ int main() { dev::Project project; - auto value = project.run("2 3 &"); + auto value = project.run("2 2 +"); if( value != polish_notation_constant::ERROR_VALUE) { diff --git a/project.cc b/project.cc index 7287fc2..072e827 100644 --- a/project.cc +++ b/project.cc @@ -37,30 +37,7 @@ value_t Project::take_value_from_stack(stack_numbers_t& stack) return value; } -value_t Project::make_operation(char type_operation, - double left_operand, - double right_operand) -{ - switch(type_operation) { - case '+': - left_operand = sum(left_operand, right_operand); - break; - case '-': - left_operand = subtract(left_operand, right_operand); - break; - case '*': - left_operand = multiplication(left_operand, right_operand); - break; - case '/': - left_operand = division(left_operand, right_operand); - break; - default: - error_code_val = error_code::NOT_CORRECT_EXPRESSION; - break; - } - return left_operand; -} bool Project::is_number(const std::string& s) { @@ -82,6 +59,28 @@ int Project::get_error_code() return static_cast(error_code_val); } +value_t Project::calculateStackValue(std::string temp_str, stack_numbers_t& stack_numbers) +{ + double left_operand, right_operand; + + right_operand = take_value_from_stack(stack_numbers); + left_operand = take_value_from_stack(stack_numbers); + + left_operand = project_operation_.make_operation(temp_str[0], left_operand, right_operand); + + if(left_operand == ERROR_VALUE) + { + error_code_val = error_code::NOT_CORRECT_EXPRESSION; + return ERROR_VALUE; + } + + if(left_operand != polish_notation_constant::ERROR_VALUE && temp_str[0] == '/') { + error_code_val = error_code::ZERO_DEVISION; + } + + return left_operand; +} + value_t Project::processData(std::string& input_str) { stack_numbers_t stack_numbers; @@ -100,55 +99,36 @@ value_t Project::processData(std::string& input_str) } else { if (true == is_valid_count_value(stack_numbers)) { - double left_operand, right_operand; + value_t value = calculateStackValue(temp_str, stack_numbers); - right_operand = take_value_from_stack(stack_numbers); - left_operand = take_value_from_stack(stack_numbers); + if (value != ERROR_VALUE){ + stack_numbers.push(value); + } + else{ + break; + } - left_operand = make_operation(temp_str[0], left_operand, right_operand); - stack_numbers.push(left_operand); + } else { + error_code_val = error_code::NOT_CORRECT_COUNT_OF_OPERATION; } } if(error_code_val != error_code::NO_ERROR) { - clear_stack(stack_numbers); - break; + clear_stack(stack_numbers); + break; } } + + if (input_str.empty()) + { + error_code_val = error_code::STACK_EMPTY; + } + if (stack_numbers.size() != 0) { return_value = stack_numbers.top(); } return return_value; } - -double Project::division(double a, double b) -{ - if (b != 0) { - return a / b; - } else { - error_code_val = error_code::ZERO_DEVISION; - - std::cout << "Devision on zero!\n"; - - return -1; - } -} - -double Project::sum(double a, double b) -{ - return a + b; -} - -double Project::subtract(double a, double b) -{ - return a - b; -} - -double Project::multiplication(double a, double b) -{ - return a * b; -} - } // namespace dev diff --git a/project.cc.autosave b/project.cc.autosave deleted file mode 100644 index 0c9b6b8..0000000 --- a/project.cc.autosave +++ /dev/null @@ -1,154 +0,0 @@ -#include "project.h" - -namespace dev { - - -value_t Project::run(std::string input_str) { - - return processData(input_str); -} - - -bool Project::is_valid_count_value(stack_numbers_t& stack) -{ - if (stack.size() < 2) { - error_code_val = error_code::NOT_CORRECT_COUNT_OF_OPERATION; - - return false; - } - else - { - return true; - } -} - -value_t Project::take_value_from_stack(stack_numbers_t& stack) -{ - value_t value = ERROR_VALUE; - - if (stack.size() != 0) { - value = stack.top(); - stack.pop(); - } - else{ - error_code_val = error_code::STACK_EMPTY; - } - - return value; -} - -value_t Project::make_operation(char type_operation, - double left_operand, - double right_operand) -{ - switch(type_operation) { - case '+': - left_operand = sum(left_operand, right_operand); - break; - case '-': - left_operand = subtract(left_operand, right_operand); - break; - case '*': - left_operand = multiplication(left_operand, right_operand); - break; - case '/': - left_operand = division(left_operand, right_operand); - break; - default: - error_code_val = error_code::NOT_CORRECT_EXPRESSION; - break; - } - - return left_operand; -} - -bool Project::is_number(const std::string& s) -{ - char* end = 0; - double val = std::strtod(s.c_str(), &end); - return end != s.c_str() && *end == '\0' && val != HUGE_VAL; -} - -void Project::clear_stack(stack_numbers_t & stack) -{ - while(!stack.empty()) - { - stack.pop(); - } -} - -int Project::get_error_code() -{ - return static_cast(error_code_val); -} - -value_t Project::processData(std::string& input_str) -{ - stack_numbers_t stack_numbers; - error_code_val = error_code::NO_ERROR; - - value_t return_value = ERROR_VALUE; - std::istringstream f(input_str); - std::string temp_str; - - - while (std::getline(f, temp_str, ' ')) { - std::cout << "Stack value: " << temp_str << std::endl; - - if(is_number(temp_str)) { - stack_numbers.push(std::stod(temp_str.c_str())); - } - else { - if (true == is_valid_count_value(stack_numbers)) { - double left_operand, right_operand; - - right_operand = take_value_from_stack(stack_numbers); - left_operand = take_value_from_stack(stack_numbers); - - left_operand = make_operation(temp_str[0], left_operand, right_operand); - stack_numbers.push(left_operand); - } - } - - if(error_code_val != error_code::NO_ERROR) { - clear_stack(stack_numbers); - break; - } - } - - if (stack_numbers.size() != 0) { - return_value = stack_numbers.top(); - } - - return return_value; -} - -double Project::division(double a, double b) -{ - if (b != 0) { - return a / b; - } else { - error_code_val = error_code::ZERO_DEVISION; - - std::cout << "Devision on zero!\n"; - - return -1; - } -} - -double Project::sum(double a, double b) -{ - return a + b; -} - -double Project::subtract(double a, double b) -{ - return a - b; -} - -double Project::multiplication(double a, double b) -{ - return a * b; -} - -} // namespace dev diff --git a/project.h b/project.h index bd5d131..022971d 100644 --- a/project.h +++ b/project.h @@ -1,6 +1,7 @@ #pragma once #include "iproject.h" #include "constant.h" +#include "project_operation.h" #include #include @@ -22,31 +23,21 @@ class Project : public IProject { public: double run(std::string); - // MOve to private section - value_t take_value_from_stack(); - - // MOve to private section - value_t make_operation(char type_operation, - double left_operand, - double right_operand); - int get_error_code(); private: - value_t processData(std::string& input_str); - - bool is_valid_count_value(stack_numbers_t&); + void clear_stack(stack_numbers_t&); + value_t calculateStackValue(std::string temp_str, stack_numbers_t& stack_numbers); + value_t take_value_from_stack(); + value_t processData(std::string& input_str); value_t take_value_from_stack(stack_numbers_t&); - value_t division (double, double); - value_t sum (double, double); - value_t subtract (double, double); - value_t multiplication (double, double); - + bool is_valid_count_value(stack_numbers_t&); bool is_number(const std::string& s); - void clear_stack(stack_numbers_t&); + + project_operation project_operation_; error_t error_code_val = error_code::NO_ERROR; }; } // namespace dev diff --git a/project_operation.cpp b/project_operation.cpp new file mode 100644 index 0000000..0bb9de6 --- /dev/null +++ b/project_operation.cpp @@ -0,0 +1,55 @@ +#include "project_operation.h" + +project_operation::project_operation() +{ + +} + +value_t project_operation::division(double a, double b) +{ + if (b != 0) { + return a / b; + } else { + return polish_notation_constant::ERROR_VALUE; + } +} + +value_t project_operation::sum(double a, double b) +{ + return a + b; +} + +value_t project_operation::subtract(double a, double b) +{ + return a - b; +} + +value_t project_operation::multiplication(double a, double b) +{ + return a * b; +} + +value_t project_operation::make_operation(char type_operation, + double left_operand, + double right_operand) +{ + switch(type_operation) { + case '+': + left_operand = sum(left_operand, right_operand); + break; + case '-': + left_operand = subtract(left_operand, right_operand); + break; + case '*': + left_operand = multiplication(left_operand, right_operand); + break; + case '/': + left_operand = division(left_operand, right_operand); + break; + default: + left_operand = ERROR_VALUE; + break; + } + + return left_operand; +} diff --git a/project_operation.h b/project_operation.h new file mode 100644 index 0000000..cfe9455 --- /dev/null +++ b/project_operation.h @@ -0,0 +1,23 @@ +#ifndef PROJECT_OPERATION_H +#define PROJECT_OPERATION_H +#include "constant.h" + +using namespace polish_notation_constant; + +class project_operation +{ + +public: + project_operation(); + + value_t make_operation(char type_operation, + double left_operand, + double right_operand); + + value_t division (double, double); + value_t sum (double, double); + value_t subtract (double, double); + value_t multiplication (double, double); +}; + +#endif // PROJECT_OPERATION_H diff --git a/test/project_test.cc b/test/project_test.cc index 892dc34..e081556 100644 --- a/test/project_test.cc +++ b/test/project_test.cc @@ -94,7 +94,7 @@ TEST_F(ProjectTest, Run_error_code_test_STACK_EMPTY) { } TEST_F(ProjectTest, Run_error_code_test_STACK_NOT_CORRECT_EXPRESSION) { - ASSERT_EQ(polish_notation_constant::ERROR_VALUE, project_.run("2 * 3")); + ASSERT_EQ(polish_notation_constant::ERROR_VALUE, project_.run("2 3 &")); ASSERT_EQ(static_cast(polish_notation_constant::error_code::NOT_CORRECT_EXPRESSION), project_.get_error_code()); } From 8b37ef8cfa46f7f57c7e6c831846b8a1da444c80 Mon Sep 17 00:00:00 2001 From: Luxuser Date: Wed, 18 Dec 2019 13:18:34 +0200 Subject: [PATCH 4/4] Init branch --- project.cc.autosave | 134 ++++++++++++++++++++++++++++++++++ test/project_test.cc.autosave | 103 ++++++++++++++++++++++++++ 2 files changed, 237 insertions(+) create mode 100644 project.cc.autosave create mode 100644 test/project_test.cc.autosave diff --git a/project.cc.autosave b/project.cc.autosave new file mode 100644 index 0000000..319eec4 --- /dev/null +++ b/project.cc.autosave @@ -0,0 +1,134 @@ +#include "project.h" + +namespace dev { + + +value_t Project::run(std::string input_str) { + + return processData(input_str); +} + + +bool Project::is_valid_count_value(stack_numbers_t& stack) +{ + if (stack.size() < 2) { + error_code_val = error_code::NOT_CORRECT_COUNT_OF_OPERATION; + + return false; + } + else + { + return true; + } +} + +value_t Project::take_value_from_stack(stack_numbers_t& stack) +{ + value_t value = ERROR_VALUE; + + if (stack.size() != 0) { + value = stack.top(); + stack.pop(); + } + else{ + error_code_val = error_code::STACK_EMPTY; + } + + return value; +} + + + +bool Project::is_number(const std::string& s) +{ + char* end = 0; + double val = std::strtod(s.c_str(), &end); + return end != s.c_str() && *end == '\0' && val != HUGE_VAL; +} + +void Project::clear_stack(stack_numbers_t & stack) +{ + while(!stack.empty()) + { + stack.pop(); + } +} + +int Project::get_error_code() +{ + return static_cast(error_code_val); +} + +value_t Project::calculateStackValue(std::string temp_str, stack_numbers_t& stack_numbers) +{ + double left_operand, right_operand; + + right_operand = take_value_from_stack(stack_numbers); + left_operand = take_value_from_stack(stack_numbers); + + left_operand = project_operation_.make_operation(temp_str[0], left_operand, right_operand); + + if(left_operand == ERROR_VALUE) + { + error_code_val = error_code::NOT_CORRECT_EXPRESSION; + return ERROR_VALUE; + } + + if(left_operand != polish_notation_constant::ERROR_VALUE && temp_str[0] == '/') { + error_code_val = error_code::ZERO_DEVISION; + } + + return left_operand; +} + +value_t Project::processData(std::string& input_str) +{ + stack_numbers_t stack_numbers; + error_code_val = error_code::NO_ERROR; + + value_t return_value = ERROR_VALUE; + std::istringstream f(input_str); + std::string temp_str; + + + while (std::getline(f, temp_str, ' ')) { + std::cout << "Stack value: " << temp_str << std::endl; + + if(is_number(temp_str)) { + stack_numbers.push(std::stod(temp_str.c_str())); + } + else { + if (is_valid_count_value(stack_numbers) == true) { + value_t value = calculateStackValue(temp_str, stack_numbers); + + if (value != ERROR_VALUE){ + stack_numbers.push(value); + } + else{ + break; + } + + } else { + error_code_val = error_code::NOT_CORRECT_COUNT_OF_OPERATION; + } + } + + if(error_code_val != error_code::NO_ERROR) { + clear_stack(stack_numbers); + break; + } + } + + + if (input_str.empty()) + { + error_code_val = error_code::STACK_EMPTY; + } + + if (stack_numbers.size() != 0) { + return_value = stack_numbers.top(); + } + + return return_value; +} +} // namespace dev diff --git a/test/project_test.cc.autosave b/test/project_test.cc.autosave new file mode 100644 index 0000000..edd1eb7 --- /dev/null +++ b/test/project_test.cc.autosave @@ -0,0 +1,103 @@ +#include "project.h" +#include "constant.h" +#include +#include +namespace dev { +namespace testing { + +class ProjectTest : public ::testing::Test { + public: + void SetUp() override {} + void TearDown() override {} + dev::Project project_; +}; + +TEST_F(ProjectTest, Run_int) { + ASSERT_EQ(3, project_.run("1 2 +")); +} + +TEST_F(ProjectTest, Run_double) { + ASSERT_EQ(3.3, project_.run("1.3 2 +")); +} + +TEST_F(ProjectTest, Run_long_expression_below_zero) { + ASSERT_EQ(-1, project_.run("1 2 - 1 + 1 -")); +} + +TEST_F(ProjectTest, Run_long_expression_complex_test) { + ASSERT_EQ(21, project_.run("1 2 + 3 4 + *")); +} + +TEST_F(ProjectTest, Run_long_expression_above_zero) { + ASSERT_EQ(49, project_.run("1 2 + 4 + 7 *")); +} + +//TEST_F(ProjectTest, Is_number_double) { +// ASSERT_EQ(true, project_.is_number("1.3")); +//} + +//TEST_F(ProjectTest, Is_number_int) { +// ASSERT_EQ(true, project_.is_number("2")); +//} + +//TEST_F(ProjectTest, Is_number_invalid) { +// ASSERT_EQ(false, project_.is_number("asdas")); +//} + +//TEST_F(ProjectTest, Sum_double) { +// ASSERT_EQ(3.1, project_.sum(1.1, 2)); +//} + +//TEST_F(ProjectTest, Sum_int) { +// ASSERT_EQ(5, project_.sum(2, 3)); +//} + +//TEST_F(ProjectTest, Devision_double) { +// ASSERT_EQ(1.3, project_.division(2.6, 2)); +//} + +//TEST_F(ProjectTest, Devision_int) { +// ASSERT_EQ(3, project_.division(6, 2)); +//} + +//TEST_F(ProjectTest, Devision_zero_devision) { +// ASSERT_EQ(-1, project_.division(6, 0)); +//} + +//TEST_F(ProjectTest, Subtract_int) { +// ASSERT_EQ(4, project_.subtract(6, 2)); +//} + +//TEST_F(ProjectTest, Subtract_double) { +// ASSERT_EQ(4.2, project_.subtract(6.2, 2)); +//} + +//TEST_F(ProjectTest, Multiplication_double) { +// ASSERT_EQ(2.4, project_.multiplication(1.2, 2)); +//} + +//TEST_F(ProjectTest, Multiplication_int) { +// ASSERT_EQ(4, project_.multiplication(2, 2)); +//} + +// to do: test all error code output from project +TEST_F(ProjectTest, Run_error_code_test_NOT_CORRECT_COUNT_OF_OPERATION) { + ASSERT_EQ(polish_notation_constant::ERROR_VALUE, project_.run("+ +")); + ASSERT_EQ(static_cast(polish_notation_constant::error_code::NOT_CORRECT_COUNT_OF_OPERATION), + project_.get_error_code()); +} + +TEST_F(ProjectTest, Run_error_code_test_STACK_EMPTY) { + ASSERT_EQ(polish_notation_constant::ERROR_VALUE, project_.run("")); + ASSERT_EQ(static_cast(polish_notation_constant::error_code::STACK_EMPTY), + project_.get_error_code()); +} + +TEST_F(ProjectTest, Run_error_code_test_STACK_NOT_CORRECT_EXPRESSION) { + ASSERT_EQ(polish_notation_constant::ERROR_VALUE, project_.run("2 3 &")); + ASSERT_EQ(static_cast(polish_notation_constant::error_code::NOT_CORRECT_EXPRESSION), + project_.get_error_code()); +} + +} // namespace testing +} // namespace dev