chapter 2.1 calculator project setup
This commit is contained in:
61
calculator/pkg/calculator.py
Normal file
61
calculator/pkg/calculator.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# calculator.py
|
||||
|
||||
class Calculator:
|
||||
def __init__(self):
|
||||
self.operators = {
|
||||
"+": lambda a, b: a + b,
|
||||
"-": lambda a, b: a - b,
|
||||
"*": lambda a, b: a * b,
|
||||
"/": lambda a, b: a / b,
|
||||
}
|
||||
self.precedence = {
|
||||
"+": 1,
|
||||
"-": 1,
|
||||
"*": 2,
|
||||
"/": 2,
|
||||
}
|
||||
|
||||
def evaluate(self, expression):
|
||||
if not expression or expression.isspace():
|
||||
return None
|
||||
tokens = expression.strip().split()
|
||||
return self._evaluate_infix(tokens)
|
||||
|
||||
def _evaluate_infix(self, tokens):
|
||||
values = []
|
||||
operators = []
|
||||
|
||||
for token in tokens:
|
||||
if token in self.operators:
|
||||
while (
|
||||
operators
|
||||
and operators[-1] in self.operators
|
||||
and self.precedence[operators[-1]] >= self.precedence[token]
|
||||
):
|
||||
self._apply_operator(operators, values)
|
||||
operators.append(token)
|
||||
else:
|
||||
try:
|
||||
values.append(float(token))
|
||||
except ValueError:
|
||||
raise ValueError(f"invalid token: {token}")
|
||||
|
||||
while operators:
|
||||
self._apply_operator(operators, values)
|
||||
|
||||
if len(values) != 1:
|
||||
raise ValueError("invalid expression")
|
||||
|
||||
return values[0]
|
||||
|
||||
def _apply_operator(self, operators, values):
|
||||
if not operators:
|
||||
return
|
||||
|
||||
operator = operators.pop()
|
||||
if len(values) < 2:
|
||||
raise ValueError(f"not enough operands for operator {operator}")
|
||||
|
||||
b = values.pop()
|
||||
a = values.pop()
|
||||
values.append(self.operators[operator](a, b))
|
||||
23
calculator/pkg/render.py
Normal file
23
calculator/pkg/render.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# render.py
|
||||
|
||||
def render(expression, result):
|
||||
if isinstance(result, float) and result.is_integer():
|
||||
result_str = str(int(result))
|
||||
else:
|
||||
result_str = str(result)
|
||||
|
||||
box_width = max(len(expression), len(result_str)) + 4
|
||||
|
||||
box = []
|
||||
box.append("┌" + "─" * box_width + "┐")
|
||||
box.append(
|
||||
"│" + " " * 2 + expression + " " * (box_width - len(expression) - 2) + "│"
|
||||
)
|
||||
box.append("│" + " " * box_width + "│")
|
||||
box.append("│" + " " * 2 + "=" + " " * (box_width - 3) + "│")
|
||||
box.append("│" + " " * box_width + "│")
|
||||
box.append(
|
||||
"│" + " " * 2 + result_str + " " * (box_width - len(result_str) - 2) + "│"
|
||||
)
|
||||
box.append("└" + "─" * box_width + "┘")
|
||||
return "\n".join(box)
|
||||
Reference in New Issue
Block a user