import re
#operation string (with parameters)
z_j_func = 'Z = 1 * 0 + 4 * 1/2 + 0 * 0 + 3 / 2 + M * 12 + M * 12 + M * 2 - 4 / 8'
Having a string like this which has parameters in some terms, how do I resolve the parameters without terms?, and then remove the terms that are 0 and join (by adding or subtracting) the terms that can be operated
z_j_func = 'Z = 0 + 2 + 0 + 3 / 2 + M * 12 + M * 12 + M * 2 - 1 / 2'
In the end it should look like this:
z_j_func = 'Z = 3 + M * 12 + M * 12 + M * 2'
In general you would use a symbolic expression parser, like sympy
.
Here is how that would work out, assuming that the string is of the form: <identifier> = <expression>
import sympy
def simplify(equation):
# Identify the operands of the equation
left, right = equation.replace(" ", "").split("=")
return f"{left} = {sympy.simplify(right)}"
# Example run
z_j_func = 'Z = 1 * 0 + 4 * 1/2 + 0 * 0 + 3 / 2 + M * 12 + M * 12 + M * 2 - 4 / 8'
print(simplify(z_j_func)) # Z = 26*M + 3
If you prefer not to use a parser, but want to throw your own, then have a look at the next piece of code. It makes several assumptions, including:
<identifier> = <expression>
;+
, -
, *
, /
;/
operator is used, it is the rightmost operator in the term;M
) only appear in numerators, not denominatorsThe code:
import re
from collections import defaultdict
from math import prod
from fractions import Fraction
def simplify(equation):
# Identify the operands of the equation
left, right = equation.replace(" ", "").split("=")
# Identify the numerators and denominators
terms = [
term.split("/") if "/" in term else [term, 1]
for term in re.split(r"\+|(?=-)", right)
]
# Group terms by the unknowns (variable) in their numerators
d = defaultdict(list)
for num, denom in terms:
d["*".join(re.findall(r"(?i)[a-z]+", num))].append(
(re.sub(r"(?i)\*[a-z]+|[a-z]+\*?", "", num), denom)
)
# Evaluate the coefficients for each unknown and concatenate
return left + " = " + " + ".join(
(key + " * " + str(Fraction(sum(
prod(map(float, num.split('*'))) / float(denom)
for num, denom in expr
)))).lstrip(" *")
for key, expr in d.items()
).replace(" + -", " - ")
z_j_func = 'Z = 1 * 0 + 4 * 1/2 + 0 * 0 + 3 / 2 + M * 12 + M * 12 + M * 2 - 4 / 8'
print(simplify(z_j_func)) # Z = M * 26 + 3