import matplotlib.pyplot as plt
string = input("Please enter a function: ")
Here the code that I want to convert. I want to convert this to variable to graph the function. Other part of the code will be:
domain = [x for x in range(-10,10)]
range = [string for x in domain]
And I want the string in range be variable in order to Python can run the code. For example if a user enter, let's say,
string = "x ** 2 + x * 2 + 1"
Then I want a method or something that will convert this string to a variable. And in the end I want to get:
string = x ** 2 + x * 2 + 1
By getting this I can get a plot from matplotlib. Finally code will be:
domain = [x for x in range(-10,10)]
range = [x ** 2 + x * 2 + 1 for x in domain]
Thanks in advance!
A quick & dirty approach would be to use the native function eval. For instance define the following high-order function:
def str_to_func(string):
return lambda x: eval(string)
which can be used in this way:
function = str_to_func(string)
values = [function(x) for x in domain]
plt.plot(domain, values)
Related
Is there a way to use sympy to find/replace all standalone integers (that aren't exponents) to 1.
For example, converting the following:
F(x) = (2/x^2) + (3/x^3) + 4
To:
F(x) = (1/x^2) + (1/x^3) + 1
I've searched extensively on stackoverflow for sympy expression.match/replace/find solutions, and have tried using a Wildcard symbol to find and replace all numbers in the expression but I keep running into the issue of matching and replacing the exponents (2 and 3 in this example) as well as they are also considered numbers.
Is there a simple (pythonic) way to achieve the above?
Thanks!
setdefault used with replace is a nice way to go. The single expression below has 3 steps:
mask off powers and record
change Rationals to 1 (to handle integers in numer or denom)
restore powers
>>> from sympy.abc import x
>>> from sympy import Dummy
>>> eq = (2/x**2) + (3/x**3) + 4 + 1/x/8
>>> reps = {}
>>> eq = eq.replace(lambda x: x.is_Pow, lambda x: reps.setdefault(x, Dummy())
).replace(lambda x: x.is_Rational, lambda x: 1
).xreplace({v:k for k,v in reps.items()})
1 + 1/x + 1/x**2 + 1/x**3
You can write a function that will recurse into your expression. For any expression expr, expr.args will give you the components of that expression. expr.is_constant() will tell you if it's a constant. expr.is_Pow will tell you if it's an exponential expression, so you can choose not to drill down into these expressions.
import sympy
def get_constants(expr):
c = set()
for x in expr.args:
if x.is_constant(): c |= {x}
if not x.is_Pow:
c |= get_constants(x)
return c
Now, you can get all the constants in said expression, and replace each of these constants using expr.replace().
def replace_constants(expr, repl):
for const in get_constants(expr):
expr = expr.replace(const, repl)
return expr
With your example expression, we get:
x = sympy.symbols('x')
F = 2/x**2 + 3/x**3 + 4
G = replace_constants(F, 1)
print(F) # 4 + 2/x**2 + 3/x**3
print(G) # 1 + x**(-2) + x**(-3)
I want to find the vertical asymptote for:
f=(3x^3 + 17x^2 + 6x + 1)/(2x^3 - x + 3)
So I want to find the roots for (2x^3 - x + 3) so I wrote:
import sympy as sy
x = sy.Symbol('x', real=True)
asym1 = sy.solve(2*x**3-x+3,x)
for i in range(len(asym1)):
asym1[i] = asym1[i].evalf()
print(asym1)
The output was:
[0.644811950742531 + 0.864492542166306*I, 0.644811950742531 -
0.864492542166306*I, -1.28962390148506]
So right now the only number that makes sense in the output is -1.289 and the complex numbers don't have any meaning.
My question is: How can I only select the real numbers so the output says:
asym1 = -1.28962390148506
you can do:
asym1 = [n for n in asym1 if n.is_real][0]
Complex numbers are instances of complex class while real numbers
are floats:
asym1 = [x for x in asym1 if isinstance(x, float)]
In order to calculate derivatives and other expressions I used the sympy package and said that T = sy.Symbol('T') now that I have calculated the right expression:
E= -T**2*F_deriv_T(T,rho)
where
def F_deriv_rho(T,rho):
ret = 0
for n in range(5):
for m in range(4):
inner= c[n,m]*g_rho_deriv_rho_np*g_T_np
ret += inner
return ret
that looks like this:
F_deriv_rho: [0.0 7.76971e-5*T 0.0001553942*T**2*rho
T*(-5.14488e-5*log(rho) - 5.14488e-5)*log(T) + T*(1.22574e-5*log(rho)+1.22574e-5)*log(T) + T*(1.89488e-5*log(rho) + 1.89488e-5)*log(T) + T(2.29441e-5*log(rho) + 2.29441e-5)*log(T) + T*(7.49956e-5*log(rho) + 7.49956e-5)*log(T)
T**2*(-0.0001028976*rho*log(rho) - 5.14488e-5*rho)*log(T) + T**2*(2.45148e-5*rho*log(rho) + 1.22574e-5*rho)*log(T) + T**2*(3.78976e-5*rho*log(rho) + 1.89488e-5*rho)*log(T) + T**2*(4.58882e-5*rho*log(rho) + 2.29441e-5*rho)*log(T) + T**2*(0.0001499912*rho*log(rho) + 7.49956e 5*rho)*log(T)]
with python I would like to change T (and rho) as a symbol to a value. How could I do that?
So, I would like to create 10 numbers like T_def = np.arange(2000, 10000, 800)and exchange all my sy.symbol(T) by iterating through the 10 values I created in the array.
Thanks for your help
I have found the solution according to this post:
How to substitute multiple symbols in an expression in sympy?
by usings "subs":
>>> from sympy import Symbol
>>> x, y = Symbol('x y')
>>> f = x + y
>>> f.subs({x:10, y: 20})
>>> f
30
There's more for this kinda thing here: http://docs.sympy.org/latest/tutorial/basic_operations.html
EDIT: A faster way would be by using "lamdify" as suggested by #Bjoern Dahlgren
x = 0.8
y = str(x)
x=x*y
print x, y
Just beginning Python, not looking to fix the code, rather work out how to justify why there is an error. I believe that this attempts to pass a string off as an integer just not sure why you can't do that.
You have this:
x = 0.8 # float
y = str(0.8)
the last line, will be equivalent to
y = "0.8" # string
then, when you do
x = x * y # float * string
you get an error, because it's not possible to multiply a string with a float. But note that you can do that with integers:
x = 3
y = str(6) # y = "6"
this will produce the output "666", because it's multiplying the string "6" 3 times.
I am trying to convert hex value to float using (Python 2.7) the following method:
def hex2float(x):
y = 0
z = x.decode('hex')
try:
y = struct.unpack('!f', z)[0]
except:
print sys.exc_info()[1]
print 'z = ' + z
print 'y = %s' % (y)
print 'x = ' + x
return
def foo28():
x = '615885' #8.9398e-039
hex2float(x)
The output is as follows:
unpack requires a string argument of length 4
z = aXĂ
y = 0
x = 615885
I notice that I get the exception message for really small values. Is there a proper way to convert hex values to floating values for such cases.
You need four bytes to unpack, so prepend null bytes if necessary:
z = x.decode('hex')
z = '\0' * (4 - len(z)) + z
Normally str.decode only outputs as much bytes as necessary to represent the value, so that's why you only see it happen for small values.
This works perfectly:
>>> z = '615885'.decode("hex")
>>> z = '\0' * (4 - len(z)) + z
>>> struct.unpack('!f', z)
(8.939797951825212e-39,)
If you're going to do doubles as well this solution still works, just change 4 to 8.