Skip to content Skip to sidebar Skip to footer

How Can I Dynamically Generate A Python Symbol Statement?

I am trying to write a routine that normalizes (rewrites) a mathematical equation that may have more than one symbol on the LHS so that it only has one. The following code illustra

Solution 1:

var('a b c') will inject symbol name 'a', 'b', 'c' into the namespace but perhaps @Blorgbeard is asking about lists or dicts because instead of creating many symbols you could put the symbols in a dictionary and then access them by name:

>>> formula=' log(x)-log(x1) =-(a+b*y)'>>> eq = Eq(*map(S, formula.split('=', 1)))
>>> v = dict([(i.name, i) for i in eq.free_symbols]); v
{'y': y, 'b': b, 'x': x, 'x1': x1, 'a': a}
>>> solve(eq, v['x'])
[x1*exp(-a - b*y)]

So it is not actually necessary to use eval or to have a variable matching a symbol name: S can convert a string to an expression and free_symbols can identify which symbols are present. Putting them in a dictionary with keys being the Symbol name allows them to be retrieved from the dictionary with a string.

Solution 2:

I think what you want to generate a string from these two statements and then you can eval that string

str_eq = f'{ss2} = {symbols(sym1)}'print(str_eq)
>>' ,SAUMMCREDBISCN,SAUNECONPRVTXN,SAUMMCREDBISCN,SAUNECONPRVTXN,SAUMMLOANINTRCN,SAUINTR,SAUNYGDPMKTPKN,SAUNYGDPGAP_, = (SAUMMCREDBISCN, SAUNECONPRVTXN, SAUMMCREDBISCN, SAUNECONPRVTXN, SAUMMLOANINTRCN, SAUINTR, SAUNYGDPMKTPKN, SAUNYGDPGAP_)'

The first line says - give me a string but run the python code between the {} before returning it. For instance

print(f'Adding two numbers: (2+3) = {2 + 3}')

>> Adding two numbers: (2+3) = 5

Solution 3:

First, maybe this could help make your code a bit denser.

If I understand correctly, you're trying to assign a variable using a list of names. You could use vars()[x]=:

import re
from sympy import symbols

symbol_names = re.findall("SAU[A-Z_]+",formula)
symbol_objs = symbols(symbol_names)

for sym_name,sym_obj inzip(symbol_names,symbol_objs):
    vars()[sym] = sym_obj

Solution 4:

A colleague of mine (Ib Hansen) gave me a very nice and elegant solution to the original problem (how to solve for the complicated expression) that by-passed the string manipulation solution that my original question was struggling with and which most answers addressed.

His solution is to use sympify and solve from sympy

from sympy import sympify, solve
import re

defnormalize(var,eq,simplify=False,manual=False):  
    '''normalize an equation with respect to var using sympy'''
    lhs, rhs = eq.split('=')
    kat = sympify(f'Eq({lhs},{rhs})')
    var_sym = sympify(var)
    out = str(solve(kat, var_sym,simplify=simplify,manual=manual))[1:-1] 
    returnf'{var} = {out}'

This works perfectly

from sympy import sympify, solve
import re

defnorm(var,eq,simplify=False,manual=False):  
    '''normalize an equation with respect to var using sympy'''
    lhs, rhs = eq.split('=')
    kat = sympify(f'Eq({lhs},{rhs})')
    var_sym = sympify(var)
    out = str(solve(kat, var_sym,simplify=simplify,manual=manual))[1:-1] # simplify takes for everreturnf'{var} = {out}'

``` Re write equation spelling out the dlog (delta log) function that python does no know, and putting log into lowe case '''

test8=norm('saummcredbiscn','log(saummcredbiscn/sauneconprvtxn) -log(saummcredbiscn(-1)/sauneconprvtxn(-1)) =-0.142368233181-0.22796245228*(log(saummcredbiscn(-1)/sauneconprvtxn(-1))+0.2*((saummloanintrcn(-1)-sauintr(-1))/100)-log(saunygdpmktpkn(-1)))+0.576050997065*saunygdpgap_/100')
print (test8)

with result

saummcredbiscn = 0.867301828366361*sauneconprvtxn*(saummcredbiscn(-1.0)/sauneconprvtxn(-1.0))**(19300938693/25000000000)*saunygdpmktpkn(-1.0)**(5699061307/25000000000)*exp(0.00576050997065*saunygdpgap_ + 0.00045592490456*sauintr(-1.0) - 0.00045592490456*saummloanintrcn(-1.0)

Post a Comment for "How Can I Dynamically Generate A Python Symbol Statement?"