-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calc #9
base: master
Are you sure you want to change the base?
Calc #9
Changes from all commits
da3665e
1db6fc8
a7fa1dd
19a9b77
a38c473
4dfa118
6a5cc3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#include "polishNotationCalc.hpp" | ||
namespace dev | ||
{ | ||
PolishCalc::PolishCalc() | ||
{ | ||
insertFunctionInsideMap(); | ||
} | ||
|
||
bool PolishCalc::isNumeric(const char num) | ||
{ | ||
double temp = num - '0'; | ||
if (temp >= 0 && temp <= 9) | ||
return true; | ||
|
||
return false; | ||
} | ||
bool PolishCalc::isOperator(const char num) | ||
{ | ||
if (num == '+' || num == '-' || num == '*' || num == '/') | ||
return true; | ||
return false; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Both solutions have the same performance |
||
|
||
double PolishCalc::calc( const std::string &str) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 3 blocks :
2 stacks :
Calculation should work with Operator/Operand or lambda types but not string. |
||
{ | ||
if (str.size() == 0) | ||
throw Exception{"Nothing to work on as Input is empty"}; | ||
for (int i = 0; i < str.size(); i++) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it possible to use iterator or range based loop? |
||
{ | ||
if (str[i] == ' ') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. avoid missing brackets even in one line if/else/while ... |
||
continue; | ||
if (isNumeric(str[i])) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to modify solution to work with negative numbers |
||
{ | ||
pushOperandInStack(str, i); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to work with some kind of tokens but not charters. |
||
|
||
} | ||
if (isOperator(str[i])) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Create separate loop to fill operator stack, operand stack an calculation based on 2 stacks |
||
{ | ||
auto operandVal = getOperandFromStack(); | ||
double res = 0; | ||
res = mOperatorMap[str[i]](operandVal.first, operandVal.second); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move calculation to the third loop |
||
mCalculatorStack.push(res); | ||
} | ||
} | ||
|
||
if (mCalculatorStack.size() > 1) | ||
throw Exception{"Not a valid string"}; | ||
|
||
return mCalculatorStack.top(); | ||
} | ||
|
||
void PolishCalc::pushOperandInStack(const std::string &str, int& curr_pos) | ||
{ | ||
double operand = 0; | ||
std::string temp = ""; | ||
while (curr_pos < str.size() && !(str[curr_pos] == ' ')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case of input like |
||
{ | ||
temp = temp + str[curr_pos]; | ||
curr_pos++; | ||
} | ||
operand = atof(temp.c_str()); | ||
mCalculatorStack.push(operand); | ||
curr_pos--; | ||
|
||
} | ||
std::pair<double, double> PolishCalc::getOperandFromStack() | ||
{ | ||
double secOperand = 0; | ||
double firstOperand = 0; | ||
if (mCalculatorStack.size() < 2) | ||
{ | ||
throw Exception{"No operand to work on"}; | ||
} | ||
secOperand = mCalculatorStack.top(); | ||
mCalculatorStack.pop(); | ||
firstOperand = mCalculatorStack.top(); | ||
mCalculatorStack.pop(); | ||
return std::make_pair(firstOperand, secOperand); | ||
} | ||
void PolishCalc::insertFunctionInsideMap() | ||
{ | ||
mOperatorMap.insert(std::make_pair('+', [](const double a, const double b) { return a + b; })); | ||
mOperatorMap.insert(std::make_pair('-', [](const double a, const double b) { return a - b; })); | ||
mOperatorMap.insert(std::make_pair('*', [](const double a, const double b) { return a * b; })); | ||
mOperatorMap.insert(std::make_pair('/', [](const double a, const double b) { | ||
if(b==0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if(0=b) |
||
{ | ||
throw Exception{"divide by zero"}; | ||
} | ||
return a / b; })); | ||
} | ||
} // namespace dev |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#pragma once | ||
#include <iostream> | ||
#include <stack> | ||
#include <utility> | ||
#include <functional> | ||
#include <string> | ||
#include <iterator> | ||
#include <map> | ||
|
||
namespace dev | ||
{ | ||
/*! | ||
* \brief Exception class for Calculator. | ||
*/ | ||
class Exception final : public std::exception | ||
{ | ||
public: | ||
template <typename T> | ||
Exception(T &&msg) | ||
: mMsg(std::forward<T>(msg)) | ||
{ | ||
} | ||
|
||
const char *what() const noexcept override | ||
{ | ||
return mMsg.c_str(); | ||
} | ||
|
||
private: | ||
const std::string mMsg; | ||
}; | ||
using functionCall = std::function<double(double, double)>; | ||
class PolishCalc | ||
{ | ||
public: | ||
double calc(const std::string &); | ||
PolishCalc(); | ||
|
||
private: | ||
bool isNumeric(const char num); | ||
bool isOperator(const char num); | ||
void insertFunctionInsideMap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to use |
||
void pushOperandInStack(const std::string &str, int& curr_pos); | ||
std::pair<double, double> getOperandFromStack(); | ||
std::stack<double> mCalculatorStack; | ||
std::map<const char, functionCall> mOperatorMap; | ||
}; | ||
|
||
} // namespace dev |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,5 @@ namespace dev { | |
int Project::run() { | ||
return 0; | ||
} | ||
|
||
} // namespace dev |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,14 @@ | ||
#pragma once | ||
#include "iproject.h" | ||
#include "string" | ||
|
||
namespace dev { | ||
namespace dev | ||
{ | ||
|
||
class Project : public IProject { | ||
// IProject interface | ||
public: | ||
int run(); | ||
}; | ||
} // namespace dev | ||
class Project : public IProject | ||
{ | ||
// IProject interface | ||
public: | ||
int run(); | ||
}; | ||
} // namespace dev |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include "project.h" | ||
#include "polishNotationCalc.hpp" | ||
#include <gmock/gmock.h> | ||
#include <gtest/gtest.h> | ||
namespace dev | ||
{ | ||
namespace testing | ||
{ | ||
|
||
class CalculatorTest : public ::testing::Test | ||
{ | ||
public: | ||
void SetUp() override {} | ||
void TearDown() override {} | ||
dev::PolishCalc project_; | ||
}; | ||
TEST_F(CalculatorTest, BasicOPTestWithInt) | ||
{ | ||
EXPECT_EQ(7, project_.calc("5 2 +")); | ||
} | ||
TEST_F(CalculatorTest, BasicOPTestWithDouble) | ||
{ | ||
EXPECT_EQ(7.8, project_.calc("5.5 2.3 +")); | ||
} | ||
TEST_F(CalculatorTest, MissingOperand) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Negative and positive test cases. |
||
{ | ||
EXPECT_ANY_THROW(project_.calc("5 +")); | ||
} | ||
TEST_F(CalculatorTest, MissingOperator) | ||
{ | ||
EXPECT_ANY_THROW(project_.calc("5 2")); | ||
} | ||
TEST_F(CalculatorTest, EmptyString) | ||
{ | ||
EXPECT_ANY_THROW(project_.calc("")); | ||
} | ||
TEST_F(CalculatorTest, DivideByZero) | ||
{ | ||
EXPECT_ANY_THROW(project_.calc("7 0 /")); | ||
|
||
} | ||
TEST_F(CalculatorTest, PerformComplexOpeartions) | ||
{ | ||
EXPECT_EQ(405, project_.calc("50 31 + 10 5 - * ")); | ||
} | ||
|
||
TEST_F(CalculatorTest, MixingDoubleAndInt) | ||
{ | ||
auto res = (int)project_.calc("12.5 3 / "); | ||
EXPECT_EQ(4, res); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,24 @@ | ||
#include "project.h" | ||
#include <gmock/gmock.h> | ||
#include <gtest/gtest.h> | ||
namespace dev { | ||
namespace testing { | ||
namespace dev | ||
{ | ||
namespace testing | ||
{ | ||
|
||
class ProjectTest : public ::testing::Test { | ||
public: | ||
void SetUp() override {} | ||
void TearDown() override {} | ||
dev::Project project_; | ||
}; | ||
class ProjectTest : public ::testing::Test | ||
{ | ||
public: | ||
void SetUp() override {} | ||
void TearDown() override {} | ||
dev::Project project_; | ||
}; | ||
|
||
TEST_F(ProjectTest, Run) { | ||
ASSERT_EQ(0, project_.run()); | ||
} | ||
TEST_F(ProjectTest, Run) | ||
{ | ||
ASSERT_EQ(0, project_.run()); | ||
} | ||
|
||
} // namespace testing | ||
} // namespace dev | ||
} // namespace testing | ||
// namespace testing | ||
} // namespace dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 Step : Create Token stack and validate it
3 step Go throw all tokens and call process to them