patternpythonMinor
Basic arithmetic calculator
Viewed 0 times
calculatorbasicarithmetic
Problem
The calculator supports the basic operators (Add,Substract,Divide,Multiply).
At the moment,
This is a work in progress. It is my first Python application so I want to get feedback before I keep on working on it.
Here is an example of how my calculator parses/processes an equation :
Given 3+3+9/3-4*2
-
Computing multiplications : 3+3+9/3-8 (Note that 4*2 is now 8)
-
Then divisions : 3+3+3-8 (9/3 = 3)
-
Then additions : 9-8 (3+3+3 = 9)
-
Finally substractions : 1 (9-8 = 1)
```
import operator
priorizedOperators = operator.getPriorizedOperators()
def calculate(args):
return _calculate(args,0)
def _calculate(equation, operatorArrayIndex):
if len(priorizedOperators) == operatorArrayIndex:
return equation;
arithmeticOperator = priorizedOperators[operatorArrayIndex]
copiedEquation = equation
try:
operatorLocation = copiedEquation.index(arithmeticOperator.getStringSign())
while True:
leftBound = _findLeftBound(equation,operatorLocation)
rightBound = _findRightBound(equation,operatorLocation)
leftValue = int(copiedEquation[leftBound:operatorLocation])
rightValue = int(copiedEquation[operatorLocation+1:rightBound])
temp = arithmeticOperator.operate(leftValue,rightValue)
#Replaces the part of the equation we just computed by the result
copiedEquation = copiedEquation[:leftBound] + str(temp) + copiedEquation[rightBound:]
#This will throw an exception if index doesn't find the operator, which ends the while loop
operatorLocation = copiedEquation.index(arithmeticOperator.getStringSign())
finally:
return _calculate(copiedEquation, operatorArrayIndex + 1)
def _findLeftBound(equation ,operatorIndex):
for leftBoundSearchIndex in reversed(range(0,operatorIndex)):
if
At the moment,
- It only works with positive integers
- I do not validate my user input
- My division rounds up if it isn't an integer
This is a work in progress. It is my first Python application so I want to get feedback before I keep on working on it.
Here is an example of how my calculator parses/processes an equation :
Given 3+3+9/3-4*2
-
Computing multiplications : 3+3+9/3-8 (Note that 4*2 is now 8)
-
Then divisions : 3+3+3-8 (9/3 = 3)
-
Then additions : 9-8 (3+3+3 = 9)
-
Finally substractions : 1 (9-8 = 1)
```
import operator
priorizedOperators = operator.getPriorizedOperators()
def calculate(args):
return _calculate(args,0)
def _calculate(equation, operatorArrayIndex):
if len(priorizedOperators) == operatorArrayIndex:
return equation;
arithmeticOperator = priorizedOperators[operatorArrayIndex]
copiedEquation = equation
try:
operatorLocation = copiedEquation.index(arithmeticOperator.getStringSign())
while True:
leftBound = _findLeftBound(equation,operatorLocation)
rightBound = _findRightBound(equation,operatorLocation)
leftValue = int(copiedEquation[leftBound:operatorLocation])
rightValue = int(copiedEquation[operatorLocation+1:rightBound])
temp = arithmeticOperator.operate(leftValue,rightValue)
#Replaces the part of the equation we just computed by the result
copiedEquation = copiedEquation[:leftBound] + str(temp) + copiedEquation[rightBound:]
#This will throw an exception if index doesn't find the operator, which ends the while loop
operatorLocation = copiedEquation.index(arithmeticOperator.getStringSign())
finally:
return _calculate(copiedEquation, operatorArrayIndex + 1)
def _findLeftBound(equation ,operatorIndex):
for leftBoundSearchIndex in reversed(range(0,operatorIndex)):
if
Solution
A few quick comments:
-
Read PEP 8, the Python style guide. In particular, Python uses lowercase_with_underscore variable names, and put commas after spaces.
-
Add some docstrings to your functions, so that it’s clear what purpose they serve in the context of your calculator. This will become useful as you extend the calculator, and you want to change existing function: you may remember what each function is for at the moment, but you may not in six months time.
-
Add more comments. Tell me why you’re doing certain operations. Anybody can read the code and see what it’s doing, but why is it doing it?
For example: after some inspection, I see that you iterate through
-
You have no error handling, which means I can enter something silly like
If you only want it to work with positive integers, then you should spit out any input that isn’t positive.
-
You claim that
My division rounds up if it isn't an integer
but this doesn’t seem to be true. For example, if I enter
-
There is no need for
operator.py:
calculator.py:
-
I would rename your
You can tidy up the function logic a little. Rather than calling out to
Or you could just use the builtin function
(Whether you use the latter depends on how much you want to reinvent the wheel.)
-
Having two functions called
-
Read PEP 8, the Python style guide. In particular, Python uses lowercase_with_underscore variable names, and put commas after spaces.
-
Add some docstrings to your functions, so that it’s clear what purpose they serve in the context of your calculator. This will become useful as you extend the calculator, and you want to change existing function: you may remember what each function is for at the moment, but you may not in six months time.
-
Add more comments. Tell me why you’re doing certain operations. Anybody can read the code and see what it’s doing, but why is it doing it?
For example: after some inspection, I see that you iterate through
prioritizedOperators to apply each operation in order (multiplication and division, then subtraction and addition).-
You have no error handling, which means I can enter something silly like
1/0 and get a ZeroDivisionError. You also claim that it only works for positive integers, but the simple examples I tried with negative integers seemed to work as well.If you only want it to work with positive integers, then you should spit out any input that isn’t positive.
-
You claim that
My division rounds up if it isn't an integer
but this doesn’t seem to be true. For example, if I enter
2/3 then I get output 0.-
There is no need for
getPriorizedOperators to be a function. Just declare the list as a variable in operator.py, then import it in calculator.py. For example:operator.py:
prioritized_operators = [
multiply_operator(),
divide_operator(),
plus_operator(),
minus_operator()
]calculator.py:
from operator import prioritized_operators-
I would rename your
_isNumber() function. It only checks if a single character is a numeral, but the name implies I might be able to pass in arbitrary-length strings. Perhaps _is_digit() would be better.You can tidy up the function logic a little. Rather than calling out to
ord(), you can also compare strings directly for the same result. For example:>>> "0" >> "0" < "x" < "9"
FalseOr you could just use the builtin function
isdigit(), and do away with your function entirely:>>> "5".isdigit()
True
>>> "x".isdigit()
False(Whether you use the latter depends on how much you want to reinvent the wheel.)
-
Having two functions called
calculate() and _calculate() is prone for confusion. Rename one or both of them to have a more specific name.Code Snippets
prioritized_operators = [
multiply_operator(),
divide_operator(),
plus_operator(),
minus_operator()
]from operator import prioritized_operators>>> "0" < "5" < "9"
True
>>> "0" < "x" < "9"
False>>> "5".isdigit()
True
>>> "x".isdigit()
FalseContext
StackExchange Code Review Q#87717, answer score: 6
Revisions (0)
No revisions yet.