chapter 2.1 calculator project setup

This commit is contained in:
2025-07-31 16:31:52 +02:00
parent f9a9c430e8
commit 3fb2ef23bf
4 changed files with 155 additions and 0 deletions

View 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
View 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)