0

I'm trying to make some program which involves typing formulas in input by a user. My code for now looks like so:

import numpy as np
n = int(input('Dim = '))
g = np.zeros((n, n))
for a in range(0, n):
    print('Define the metric. \n g_', a, a,'=')
    metric_component = 'lambda x, y: ' + str(input())
    g[a, a] = eval(metric_component)
print(g)

I tried to search for answers but those i found didn't work. eval() function gives me error there: float() argument must be a string or a number, not 'function': sympify() gives basically the same "can't convert expression to float" Also i want to work on those constants not their numeric values, so i'm interesting to keep them through all program and have the final output expressed by them. Is it even possible?

smichr
  • 16,948
  • 2
  • 27
  • 34
BlueHead
  • 26
  • 1
  • 3
    Please provide a minimal reproducible example, and the full error traceback. You refer to `float()` and `sympify()` which aren't in your code block... – user1558604 Dec 10 '19 at 14:58
  • I didn't think you could eval a lambda, but what are x and y if the input only returns one value? – OneCricketeer Dec 10 '19 at 15:01
  • @user1558604: I think `float()` would refer to [the builtin `float()`](https://docs.python.org/3/library/functions.html#float). But there's no apparent reference to `float()` here, and I have no idea what `sympify()` could be. – Fred Larson Dec 10 '19 at 15:02
  • @user1558604, i referred to `eval()` and just copied the text of error that's float() came from. – BlueHead Dec 10 '19 at 15:03
  • @FredLarson, https://stackoverflow.com/questions/15369106/input-a-symbolic-function-in-a-python-code - that reference i've tried. – BlueHead Dec 10 '19 at 15:05
  • @cricket_007 https://stackoverflow.com/questions/41725646/python-user-input-equation there was lambda evaluation and looks like it worked. – BlueHead Dec 10 '19 at 15:07
  • And x and y are some constants. I just wanna have a matrix with let's say element 1 - 2*x/y. To use it later, for example for differentiation. – BlueHead Dec 10 '19 at 15:09
  • 1
    @SomeShadeOfBlue: Ah, there's a "sympy" module. Never heard of it before. I added a [sympy] tag to your post, so maybe we'll attract some people who know that module. – Fred Larson Dec 10 '19 at 15:10
  • @SomeShadeOfBlue, what are you putting in the `input()`. Also include the full error as that can help provide some guidance. – user1558604 Dec 10 '19 at 15:33

1 Answers1

1

input() will return a string

>>> type(input())  # I type 1
1
<class 'str'>

So if you are expecting numeric input from the user and it can be non-integer, then just wrap the input with float. import numpy as np n = int(input('Dim = ')) g = np.zeros((n, n)) for a in range(0, n): print('Define the metric. \n g_', a, a,'=') g[a, a] = float(input()) print(g)

It's hard to tell what you want to be able to interpret from the user. If the user is going to give some expression of x and y and you are going to replace both those values with a you would either have to build a lambda that could be evaluated or do a substitution into a sympified expression:

>>> eval('(lambda x,y:'+'x + 2*y'+')(%s,%s)'%(a,a))
3*a
>>> sympify('x+2*y').subs(dict(x=a,y=a))
3*a

If you want the user to input expressions and then do something to them later, SymPy is ideally suited for this. Here, the user is prompted to fill items in a list and then those items are differentiated wrt x. It's just a toy example:

>>> from sympy import S  # shortcut for sympify
>>> from sympy.abc import x
>>> [S(input('?')) for i in range(2)]
?R**2
?R**2*sin(x)**2
[R**2, R**2*sin(x)**2]
>>> [i.diff(x) for i in _]
[0, 2*R**2*sin(x)*cos(x)]
smichr
  • 16,948
  • 2
  • 27
  • 34
  • What i want is to create a matrix, which will contain some constants and will depend from some variables. Constants and variables won’t be defined as some values, they’re just constants. So my output should look like: [[const*x, 0], [0, anotherconst*cos(y)]] for example. – BlueHead Dec 10 '19 at 20:11
  • Please show what the user would input and what the program would output for a simple case. From what you have shown it looks like the user would enter a and b and you would output `[[a*x, 0], [0, b*cos(y)]]`. And then what are you going to do with the output matrix? – smichr Dec 10 '19 at 20:21
  • Idealy i want user to input n formulas, which are containing constants and variables. That would be a metric for space i want to use. So lets set dim=2 and user's inputs are 'R^2' and 'R^2 * sin(x)^2'. And then i would like python to interpret that as an equation, because next i'll (try to) take a derivative of g[2,2] with respect to x for example. – BlueHead Dec 10 '19 at 20:50
  • see answer for example – smichr Dec 10 '19 at 20:59
  • Hm, is it a list named S? i'm kinda confused about that code. I'm sorry for maybe dumb questions. – BlueHead Dec 10 '19 at 21:15
  • see updated example -- S is shorthand for `sympify`. – smichr Dec 10 '19 at 22:23
  • Thank you for your help, I'm really appreciate that! I tried to use your answer, but that doesn't work unfortunately. `import numpy as np from sympy import S, Symbol from sympy.abc import x n = int(input('Dim = ')) g = np.zeros((n, n)) R = Symbol('R') A = [S(input('?')) for i in range(n)] B = [i.diff(x) for i in range(0, n)] print(A) print(B) ` Gave an error: Traceback (most recent call last): File "/Users/violet-mac/Desktop/python/new/venv/new.py", line 8, in B = [i.diff(x) for i in range(0, n)] AttributeError: 'int' object has no attribute 'diff' – BlueHead Dec 12 '19 at 10:29
  • You are differntiating `i`. I suspect you intended `B = [i.diff(x) for i in A]`. – smichr Dec 12 '19 at 12:48