Skip to content

Commit c4fcd9a

Browse files
committed
Add MathREPL, a math expression evaluator using eval()
1 parent de036ef commit c4fcd9a

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

python-eval-mathrepl/mathrepl.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env python3
2+
3+
# File: mathrepl.py
4+
5+
"""MathREPL, a math expression evaluator using Python's eval() and math."""
6+
7+
import math
8+
9+
__version__ = "1.0"
10+
__author__ = "Leodanis Pozo Ramos"
11+
12+
ALLOWED_NAMES = {
13+
name: obj
14+
for name, obj in math.__dict__.items()
15+
if "__" not in name
16+
}
17+
18+
PS1 = "mr>>"
19+
20+
WELCOME = f"""
21+
MathREPL {__version__}, your Python math expressions evaluator!
22+
Enter a valid math expression after the prompt "{PS1}".
23+
Type "help" for more information.
24+
Type "quit" or "exit" to exit.
25+
"""
26+
27+
USAGE = f"""
28+
Usage:
29+
Build math expressions using numeric values and operators.
30+
Use any of the following functions and constants:
31+
32+
{', '.join(ALLOWED_NAMES)}
33+
"""
34+
35+
36+
def evaluate(expression: str) -> float:
37+
"""Evaluate a math expression."""
38+
# Compile and validate syntax
39+
try:
40+
code = compile(expression, "<string>", "eval")
41+
except SyntaxError:
42+
raise SyntaxError("Invalid input expression")
43+
44+
# Validate allowed names
45+
for name in code.co_names:
46+
if name not in ALLOWED_NAMES:
47+
raise NameError(f'The use of "{name}" is not allowed')
48+
49+
return eval(code, {"__builtins__": {}}, ALLOWED_NAMES)
50+
51+
52+
def main() -> None:
53+
"""Main loop: Read and evaluate user input."""
54+
print(WELCOME)
55+
while True:
56+
# Read user's input
57+
try:
58+
expression = input(f"{PS1} ")
59+
except (KeyboardInterrupt, EOFError):
60+
raise SystemExit()
61+
62+
# Handle special commands
63+
if expression.lower() == "help":
64+
print(USAGE)
65+
continue
66+
if expression.lower() in {"quit", "exit"}:
67+
raise SystemExit()
68+
69+
# Evaluate the expression
70+
try:
71+
result = evaluate(expression)
72+
except Exception as err:
73+
print(err)
74+
75+
# Print the result
76+
print(f"The result is: {result}")
77+
78+
79+
if __name__ == "__main__":
80+
main()

0 commit comments

Comments
 (0)