I am trying to make an algebraic calculator using python, with an input like so:
eg1. x=1, x+5
eg2. x=6+12
resulting in output:
eg1. 6
eg2. x=18
So far my code looks like so:
def algebraic_calculator():
variables = {}
while True:
user_input = input("Enter expression (or 'quit' to exit): ").strip()
if user_input.lower() == 'quit':
break
try:
if '=' in user_input:
# Handle assignment like x=1 or x=6+12
var, expr = user_input.split('=')
var = var.strip()
expr = expr.strip()
variables[var] = eval(expr, {}, variables)
print(f"{var} = {variables[var]}")
else:
# Evaluate expression using stored variables
result = eval(user_input, {}, variables)
print(f"Result: {result}")
except Exception as e:
print(f"Error: {e}")
algebraic_calculator()
This is a sample interaction:
Enter expression (or 'quit' to exit): x=1, x+1
Error: name 'x' is not defined
How would I fix it to properly accept equations in the previously mentioned format (eg1, eg2) and provide a suitable response?
Here is your solution:
At the time of developing the code, there was no specified requirement for handling user input (this requirement was introduced later). Consequently, I initially used
eval()
due to its performance advantages. However,eval()
is not suitable for processing external input safely, I have since replaced it withsympify()
for improved security and symbolic expression handling.
from sympy import symbols, sympify
import re
def algebraic_calculator(input_str):
context = {}
expressions = input_str.split(',')
for expr in expressions:
expr = expr.strip()
assign_match = re.match(r'^([a-zA-Z_]\w*)\s*=\s*(.+)$', expr)
if assign_match:
var_name, value_expr = assign_match.groups()
var = symbols(var_name)
try:
value = sympify(value_expr, locals=context)
context[var_name] = value
print(f"{var_name} = {value}")
except Exception as e:
print(f"Error parsing assignment '{expr}': {e}")
else:
try:
result = sympify(expr, locals=context)
print(f"{expr} = {result}")
except Exception as e:
print(f"Error parsing expression '{expr}': {e}")
algebraic_calculator("x=1, x+5")
algebraic_calculator("x=6+12")
The algebraic_calculator
function leverages the sympy
library to parse and compute algebraic assignments and expressions. It accepts a string of comma-separated inputs, such as variable assignments (e.g., x = 6 + 12
) or expressions (e.g., x + 5
), and processes each one sequentially. Variable assignments are identified using regular expressions, then converted into symbolic form using sympy.symbols()
and evaluated with sympify()
, which also supports using previously defined variables. Non-assignment expressions are similarly evaluated using sympify()
in the context of the current variable environment. This approach enables reliable and secure algebraic manipulation, making it particularly suitable for symbolic mathematics tasks while avoiding the risks associated with Python's native eval()
function.
For detailed information on the sympify
function, please refer to: https://www.tutorialspoint.com/sympy/sympy_sympify_function.htm
For additional details on the symbols
function, kindly see: https://www.tutorialspoint.com/sympy/sympy_symbols.htm
sympify
is much safer than Python’s built-in eval()
, but it is not completely risk-free in all scenarios. For performance considerations, the following code may be appropriate, particularly in scenarios where security is not a concern and no user input is involved.
import re
def algebraic_calculator(input_str):
variables = {}
expressions = input_str.split(',')
for expr in expressions:
expr = expr.strip()
assign_match = re.match(r'^([a-zA-Z_]\w*)\s*=\s*(.+)$', expr)
if assign_match:
var, value_expr = assign_match.groups()
try:
value = eval(value_expr, {}, variables)
variables[var] = value
print(f"{var} = {value}")
except Exception as e:
print(f"Error evaluating assignment '{expr}': {e}")
else:
try:
result = eval(expr, {}, variables)
print(f"{expr} = {result}")
except Exception as e:
print(f"Error evaluating expression '{expr}': {e}")
algebraic_calculator("x=1, x+5")
algebraic_calculator("x=6+12")
Output:
x = 1
x+5 = 6
x = 18