🛠
Practice Projects · ★
String parsing · Functions · Error handling
Project 3 — Calculator
Build a command-line calculator that parses infix expressions (+, -, *, /, **, %) and handles division-by-zero and invalid input gracefully.
input parsingtry/exceptfunctionseval-safe
Duration
⏱ 1.5 hours
Level
📊 Basic Applied
Prerequisite
🎯 Basic Week 9
OUTCOME
A robust CLI calculator with history and safe expression evaluation
What you'll learn
- 1Parse and evaluate arithmetic expressions
- 2Handle errors gracefully (division by zero, invalid input)
- 3Store and display calculation history
- 4Support multi-step calculations (ANS reference)
Project Overview
- Evaluate expressions like: 3 + 4 * 2, (10 - 3) ** 2
- Commands: history, clear, quit
- ANS refers to the previous result
- Never use eval() — parse manually or use a safe alternative
Sample Session
text
Calculator (type 'quit' to exit)
> 3 + 4 * 2
= 11
> (10 - 3) ** 2
= 49
> ANS + 1
= 50
> 10 / 0
Error: division by zero
> history
3 + 4 * 2 = 11
(10 - 3) ** 2 = 49
ANS + 1 = 50💻 Examples
Run these examples and check the output yourself.
solution.py— Safe calculator with history
CODE
import re
def safe_eval(expr, ans):
expr = expr.replace("ANS", str(ans))
# Allow only numbers, operators, parens, spaces
if not re.fullmatch(r'[\d.+\-*/%(). \*\*]+', expr):
raise ValueError("Invalid characters in expression")
try:
return eval(compile(expr, "<string>", "eval"),
{"__builtins__": {}}, {})
except ZeroDivisionError:
raise ZeroDivisionError("division by zero")
history, ans = [], 0
print("Calculator (type 'quit' to exit)")
while True:
line = input("> ").strip()
if line.lower() in ("quit", "exit"): break
if line.lower() == "history":
for h in history: print(f" {h}")
continue
if line.lower() == "clear":
history.clear(); ans = 0; continue
try:
result = safe_eval(line, ans)
print(f"= {result}")
history.append(f"{line} = {result}")
ans = result
except Exception as e:
print(f"Error: {e}")
📝 Exercises
Try them yourself first, then open the solution to compare.
Exercise 1
Build the calculator
Goal: Implement expression evaluation, history, ANS, and error handling.
Requirements
- Evaluate +, -, *, /, **, %
- ANS references previous result
- Division by zero handled gracefully
- history command shows calculation log
Example code / lecture materials
All lecture materials and example code are openly available on GitHub.
View on GitHub ↗