How to manage undefined variables in a calculation - python

I have some predefined variables and some preexisted formulas(all multiplications). Formulas are calculating as expected besides when any of the variables are not defined.
Knowing that my formulas only handle multiplications I was thinking to give the value =1 to any undefined variable, in that way the calculation does break.
Is there any way to loop through the formulas, isolate the undefined variables and give them a value =1?
In the example below, ‘k’ is not defined and this calculation(kbd=kbd) is generating an error
#defined variables
a=10
b=5
c=3
d=6
e=7
f=2
g=9
#preexisted formulas
abc=a*b*c
fed=d*e*f
efg=e*f*g
kbd=k*b*d
NameError Traceback (most recent call last)
<ipython-input-10-f9e3059809fc> in <module>
----> 1 kbd=k*b*d
NameError: name 'k' is not defined

You can use something like this:
a=10
b=5
c=3
d=6
e=7
f=2
g=9
formulas = ['a*b*c','d*e*f','e*f*g','k*b*d']
for form in formulas:
variables = form.split('*')
for v in variables:
if v not in locals():
locals()[v]=1
eval(form)

Sympy is made for addressing your title 'How to manage undefined variables in a calculation'. The variables can be defined as Sympy symbols:
from sympy import *
from sympy.abc import a, b, c, d, e, f, g, k
# alternative of above line `a, b, c, d, e, f, g, k=symbols('a b c d e f g k')`
a=10
b=5
c=3
d=6
e=7
f=2
g=9
abc = a*b*c
fed = sympify(d*e*f) #you can convert an arbitrary expression to a type that can be used inside SymPy, based on https://docs.sympy.org/latest/modules/evalf.html; not really necessary for these multiplication examples
efg=e*f*g
kbd = k*b*d
print(N(abc)) #based on https://docs.sympy.org/latest/modules/evalf.html
print(abc)
print(fed) #based on https://docs.sympy.org/latest/modules/evalf.html
print(fed.evalf()) #based on https://docs.sympy.org/latest/modules/evalf.html
print(kbd)
print(simplify(kbd)) # based on https://www.tutorialspoint.com/sympy/sympy_simplification.html
kbd # - or `simplify(kbd)` - as last line in a Jupyter cell, you'll see fancy `30k` with `k` in italics in out cell.
That last line won't do anything in a script though, yet the output will look fancy in a Jupyter cell using the Python kernel where you've run %pip install sympy in the cell above. (You can try that in the cell of a Jupyter notebook here.)
Output from the print commands:
150.000000000000
84
84.0000000000000
30*k
30*k
Seen in 'Out' cell if run in Jupyter:
30𝑘

Related

Input arguments for MATLAB Engine function

I'm trying to use MATLAB engine to call a MATLAB function in Python, but I'm having some problems. After manage to deal with NumPy arrays as input in the function, now I have some error from MATLAB:
MatlabExecutionError: Undefined function 'simple_test' for input
arguments of type 'int64'.
My Python code is:
import numpy as np
import matlab
import matlab.engine
eng = matlab.engine.start_matlab()
eng.cd()
Nn = 30
x= 250*np.ones((1,Nn))
y= 100*np.ones((1,Nn))
z = 32
xx = matlab.double(x.tolist())
yy = matlab.double(y.tolist())
Output = eng.simple_test(xx,yy,z,nargout=4)
A = np.array(Output[0]).astype(float)
B = np.array(Output[1]).astype(float)
C = np.array(Output[2]).astype(float)
D = np.array(Output[3]).astype(float)
and the Matlab function is:
function [A,B,C,D] = simple_test(x,y,z)
A = 3*x+2*y;
B = x*ones(length(x),length(x));
C = ones(z);
D = x*y';
end
Is a very simple example but I'm not able to run it!
I know the problem is in the z variable, because when I define z=32 the error is the one I mentioned, and when I change for z=32. the error changes to
MatlabExecutionError: Undefined function 'simple_test' for input
arguments of type 'double'.
but I don't know how to define z.

Sharing variables across modules

I have a program- main.py that generates values for a few parameters depending on the user provided inputs. I need to share these variables with other modules- aux.py. To do that I did the following (simplified code below) -
This the main.py file:
# these three variables are dynamically calculated depending on the user provided input
a = 12
b = 13
c = 14
def declare_global():
global a, b, c
declare_global()
import aux
aux.print_all()
This is the aux.py file
def print_all():
a = globals()['a']
b = globals()['b']
c = globals()['c']
print(a)
print(b)
print(b)
Running the main.py file results in the following error
Traceback (most recent call last): File
"/Users/new/Library/Preferences/PyCharmCE2018.3/scratches/global_experiment/main.py",
line 13, in
aux.print_all() File "/Users/new/Library/Preferences/PyCharmCE2018.3/scratches/global_experiment/aux.py",
line 2, in print_all
a = globals()['a'] KeyError: 'a'
There is a very similar post addressing the same issue here but the posts there suggest adding all global variables to a new file and then importing the created file. But I cannot do that as I'll have no prior information as to what values these variables will take.
So, how do I share variables across modules?
EDIT
I lost some complexity of the actual program in order to make a minimalistic example. The reason I cannot pass the variables a,b,c to the print_all function is because in the actual program, the variables a,b,c are not serializable. They are spark dataframe objects. And one of the modules I use there (which here I am representing by print_all) serializes all its inputs I end up with an error (spark dataframes aren't serializable). Using a few workarounds I have arrived here where I use global variables and no inputs to the functions.
a = 12
b = 13
c = 14
import aux
aux.print_all(a, b, c)
Then your aux file will become:
def print_all(a, b, c):
a = globals()['a']
b = globals()['b']
c = globals()['c']
print(a)
print(b)
print(b)

Error with quantifier in Z3Py

I would like Z3 to check whether it exists an integer t that satisfies my formula. I'm getting the following error:
Traceback (most recent call last):
File "D:/z3-4.6.0-x64-win/bin/python/Expl20180725.py", line 18, in <module>
g = ForAll(t, f1(t) == And(t>=0, t<10, user[t].rights == ["read"] ))
TypeError: list indices must be integers or slices, not ArithRef
Code:
from z3 import *
import random
from random import randrange
class Struct:
def __init__(self, **entries): self.__dict__.update(entries)
user = [Struct() for i in range(10)]
for i in range(10):
user[i].uid = i
user[i].rights = random.choice(["create","execute","read"])
s=Solver()
f1 = Function('f1', IntSort(), BoolSort())
t = Int('t')
f2 = Exists(t, f1(t))
g = ForAll(t, f1(t) == And(t>=0, t<10, user[t].rights == ["read"] ))
s.add(g)
s.add(f2)
print(s.check())
print(s.model())
You are mixing and matching Python and Z3 expressions, and while that is the whole point of Z3py, it definitely does not mean that you can mix/match them arbitrarily. In general, you should keep all the "concrete" parts in Python, and relegate the symbolic parts to "z3"; carefully coordinating the interaction in between. In your particular case, you are accessing a Python list (your user) with a symbolic z3 integer (t), and that is certainly not something that is allowed. You have to use a Z3 symbolic Array to access with a symbolic index.
The other issue is the use of strings ("create"/"read" etc.) and expecting them to have meanings in the symbolic world. That is also not how z3py is intended to be used. If you want them to mean something in the symbolic world, you'll have to model them explicitly.
I'd strongly recommend reading through http://ericpony.github.io/z3py-tutorial/guide-examples.htm which is a great introduction to z3py including many of the advanced features.
Having said all that, I'd be inclined to code your example as follows:
from z3 import *
import random
Right, (create, execute, read) = EnumSort('Right', ('create', 'execute', 'read'))
users = Array('Users', IntSort(), Right)
for i in range(10):
users = Store(users, i, random.choice([create, execute, read]))
s = Solver()
t = Int('t')
s.add(t >= 0)
s.add(t < 10)
s.add(users[t] == read)
r = s.check()
if r == sat:
print s.model()[t]
else:
print r
Note how the enumerated type Right in the symbolic land is used to model your "permissions."
When I run this program multiple times, I get:
$ python a.py
5
$ python a.py
9
$ python a.py
unsat
$ python a.py
6
Note how unsat is produced, if it happens that the "random" initialization didn't put any users with a read permission.

python integration issue, the function with exponential

I would like to integrate the function e^(-x**2/2) by simpson rule
but it is keep having an error and I don't know what is the problem.
a=eval(input('a:'))
b=eval(input('b:'))
n=eval(input('n:'))
def f(x):
e**(-x**2/2)
h=(b-a)/n
s= f(a)+f(b)
def simpson_rule(f(x),a,b,n):
#Approximation by Simpson's rule
c=(a+b)/2.0
h=abs(b-a)/2.0
return h*(f(a)+4.0*f(c)+f(b))/3.0
def simpson_rule(f(x),a,b,n):
"""Approximates the definite integral of f from a to b by the composite Simpson's rule, using n subintervals"""
for i in range (1,n,2):
s+=4*f(a+i*h)
for i in range(2,n-1,2):
s+=2*f(a+i*h)
return s*h/3
print simpson_rule(f(x),a,b,n)
You define 2 integration routines with the same name. Which one do you expect to run if you call simpson_rule()?
The first one is the special case where n=1. You might rename it accordingly.
Second, your call is print simpson_rule(f(x),a,b,n) but you only need to hand over f() to the function, like this print simpson_rule(f,a,b,n).
You can see that f is a function, and f() is a function return value:
def f(x):
return x + 13
f
<function f at 0x0000000002253D68>
f(5)
18
Try it out and if you still have errors please post the error message(s).

Theano import error: cannot import name stacklists

from theano.tensor import stacklists, scalars, matrices
from theano import function
a, b, c, d = scalars('abcd')
X = stacklists([[a, b], [c, d]])
f = function([a, b, c, d], X)
f(1, 2, 3, 4)
this is my program.
i am getting following error.can anybody help
ImportError Traceback (most recent call last)
<ipython-input-17-e4e1f4f75320> in <module>()
----> 1 from theano.tensor import stacklists, scalars, matrices
2 from theano import function
3 a, b, c, d = scalars('abcd')
4 X = stacklists([[a, b], [c, d]])
5 f = function([a, b, c, d], X)
ImportError: cannot import name stacklists
You probably have an old version of Theano; stacklist was recently introduced/renamed (a month ago). Sou you should update to the latest/dev version. If you want to stay in your version try importing tensor_of_scalars instead of stacklist.
To update follow the instructions here.
This error can be caused by one of two things.
The first one is pretty obvious: does theano.tensor define a name stacklists? Should it be, for example, stacklist?
Secondly, it can happen if something else you're importing has already imported the name in a way where doing so again would cause a circular reference. The second would have to be fixed by looking at your source files.

Categories