Complete Implementation
Python
import math
import operator
class Calculator:
OPERATIONS = {
"+": operator.add, "-": operator.sub,
"*": operator.mul, "/": operator.truediv,
"**": operator.pow, "%": operator.mod,
}
def __init__(self):
self.history = []
def calculate(self, a, op, b):
if op not in self.OPERATIONS:
raise ValueError(f"Unknown operator: {op}")
if op == "/" and b == 0:
raise ZeroDivisionError("Cannot divide by zero")
result = self.OPERATIONS[op](a, b)
self.history.append(f"{a} {op} {b} = {result}")
return result
def sqrt(self, n):
if n < 0:
raise ValueError("Cannot take sqrt of negative number")
result = math.sqrt(n)
self.history.append(f"sqrt({n}) = {result}")
return result
def main():
calc = Calculator()
print("Python Calculator | ops: + - * / ** % | sqrt | history | quit")
while True:
try:
expr = input("> ").strip().lower()
if expr == "quit": break
if expr == "history":
print("\n".join(f" {i+1}. {e}" for i, e in enumerate(calc.history)) or "No history.")
continue
if expr.startswith("sqrt "):
print(calc.sqrt(float(expr[5:])))
continue
parts = expr.split()
if len(parts) == 3:
a, op, b = float(parts[0]), parts[1], float(parts[2])
print(calc.calculate(a, op, b))
else:
print("Format: ")
except (ValueError, ZeroDivisionError) as e:
print(f"Error: {e}")
except KeyboardInterrupt:
break
if __name__ == "__main__":
main() Running
Bash
python calculator.py
# > 5 + 3 โ 8.0
# > sqrt 16 โ 4.0
# > historyTip: Add a Tkinter GUI using the same Calculator class โ great practice for separating logic from presentation.