Python 代码赢得';因为某种原因我不能完全跑
我正在为一个数学计算器编写代码,遇到了一个问题。当我要求用户输入一个要推导的函数时,他们输入一个数字,然后输入x,比如3x,而不是3*x。代码崩溃,因为它无法解析它。为了解决这个问题,我有一个函数来清理它,但由于某些原因它甚至不会运行Python 代码赢得';因为某种原因我不能完全跑,python,sympy,Python,Sympy,我正在为一个数学计算器编写代码,遇到了一个问题。当我要求用户输入一个要推导的函数时,他们输入一个数字,然后输入x,比如3x,而不是3*x。代码崩溃,因为它无法解析它。为了解决这个问题,我有一个函数来清理它,但由于某些原因它甚至不会运行 class Derivatives: def __init__(self): x=sympy.Symbol('x') self.func=self.clean_func((input("Enter f(x): ")))
class Derivatives:
def __init__(self):
x=sympy.Symbol('x')
self.func=self.clean_func((input("Enter f(x): ")))
print(self.func)
print(sympy.diff(self.func, x))
def clean_func(self, func):
clean_func=""
print("c")
for i in range(len(func)):
if func[i].isalpha or isinstance(func[i], int) or func[i] in self.math_symbols :
if func[i]== "^" :
clean_func+="**"
else:
clean_func+=func[i]
for c in range(48, 57) :
if func[i:i+1] == (chr(c) + 'x') :
clean_func+="*" #helps with parsing
return clean_func
我在a=Derivatives()
输入f(x):3x
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
a=衍生工具()
文件“/Volumes/PROJECTS/M_series.py”,第71行,在__
x=符号('x')
文件“/Users/thomastierney/anaconda/lib/python3.5/site packages/sympy/core/function.py”,第1691行,格式不同
返回导数(f,*符号,**kwargs)
文件“/Users/thomastierney/anaconda/lib/python3.5/site packages/sympy/core/function.py”,第1018行,在新的__
expr=sympify(expr)
sympify中的文件“/Users/thomastierney/anaconda/lib/python3.5/site packages/sympy/core/sympify.py”,第324行
引发SympifyError('无法分析%r'%a,exc)
SympifyError:表达式“的Sympify”无法分析“3x”失败,因为引发了异常:
SyntaxError:无效语法(,第1行)
有几个问题:
func
作为字符串的名称是有误导性的(Python允许使用一阶函数,因此您希望它实际上是一个函数);让我们把它叫做fn\u str
clean_func
工作正常,它将返回一个sympy
-可解析字符串-然后将其传递到diff
,而不从字符串转换为函数for i in range(len(mystring)):
do_something(mystring[i])
更清楚地写为
for ch in mystring:
do_something(ch)
isinstance(func[i],int)
不起作用,因为func[i]
是一个单字符字符串,而不是整数。请尝试使用str.isdecimal()self.math\u符号
未定义mystring+=ch
时,它实际上会创建一个全新的字符串。因此,在字符串块列表中追加内容,然后在完成后将其添加到“”。join()
会更加有效用于范围(48,57)中的c
:Python范围不包括end
值,即这将产生48,49,50。。。56这意味着chr(57)ie“9”从未进行过测试end
偏移量,因此func[i:i+1]
是一个字符,完全等同于func[i]
。你的意思是func[i:i+2]
3.
的代码是一个有效的Python浮点值,但是您的代码将无法捕获3.x
。进行适当的标记化而不是逐个字符的比较将抓住这一点import string
import sympy
# This could easily be just a function;
# I made it a class to keep the namespace clean
class FnStrCleaner:
# valid characters
NUMCHARS = set(string.digits + ".")
VARCHARS = set(string.ascii_letters)
OPCHARS = set("()+-*/^")
LEGALCHARS = NUMCHARS | VARCHARS | OPCHARS
@classmethod
def clean(cls, fn_str):
# generator expression - skip nonlegal chars
good_chars = (ch for ch in fn_str if ch in cls.LEGALCHARS)
out = []
# simple FSM to process character stream
prev_num = False # preceding character was part of a number
for ch in good_chars:
if prev_num:
if ch in cls.NUMCHARS:
out.append(ch)
# prev_num = True
elif ch in cls.VARCHARS:
out.append('*' + ch)
prev_num = False
else: # ch in cls.OPCHARS
out.append(ch)
prev_num = False
else:
if ch in cls.NUMCHARS:
out.append(ch)
prev_num = True
elif ch in cls.VARCHARS:
out.append(ch)
# prev_num = False
else: # ch in cls.OPCHARS
out.append('**' if ch == '^' else ch)
# prev_num = False
return "".join(out)
def get_function(prompt, locals=None):
fn_str = input(prompt)
fn_str = FnStrCleaner.clean(fn_str)
return sympy.sympify(fn_str, locals=locals)
def main():
x = sympy.Symbol("x")
f = get_function("Enter f(x): ", {'x': x})
df = sympy.diff(f, x)
print("f(x) =", f)
print("f'(x) =", df)
if __name__ == "__main__":
main()
就像
Enter f(x): 29x^3 + 12x^2 - 9x + 5
f(x) = 29*x**3 + 12*x**2 - 9*x + 5
f'(x) = 87*x**2 + 24*x - 9
有几个问题:
func
作为字符串的名称是有误导性的(Python允许使用一阶函数,因此您希望它实际上是一个函数);让我们把它叫做fn\u str
clean_func
工作正常,它将返回一个sympy
-可解析字符串-然后将其传递到diff
,而不从字符串转换为函数for i in range(len(mystring)):
do_something(mystring[i])
更清楚地写为
for ch in mystring:
do_something(ch)
isinstance(func[i],int)
不起作用,因为func[i]
是一个单字符字符串,而不是整数。请尝试使用str.isdecimal()self.math\u符号
未定义mystring+=ch
时,它实际上会创建一个全新的字符串。因此,在字符串块列表中追加内容,然后在完成后将其添加到“”。join()
会更加有效用于范围(48,57)中的c
:Python范围不包括end
值,即这将产生48,49,50。。。56这意味着chr(57)ie“9”从未进行过测试end
偏移量,因此func[i:i+1]
是一个字符,完全等同于func[i]
。你的意思是func[i:i+2]
3.
的代码是一个有效的Python浮点值,但是您的代码将无法捕获3.x
。进行适当的标记化而不是逐个字符的比较将抓住这一点import string
import sympy
# This could easily be just a function;
# I made it a class to keep the namespace clean
class FnStrCleaner:
# valid characters
NUMCHARS = set(string.digits + ".")
VARCHARS = set(string.ascii_letters)
OPCHARS = set("()+-*/^")
LEGALCHARS = NUMCHARS | VARCHARS | OPCHARS
@classmethod
def clean(cls, fn_str):
# generator expression - skip nonlegal chars
good_chars = (ch for ch in fn_str if ch in cls.LEGALCHARS)
out = []
# simple FSM to process character stream
prev_num = False # preceding character was part of a number
for ch in good_chars:
if prev_num:
if ch in cls.NUMCHARS:
out.append(ch)
# prev_num = True
elif ch in cls.VARCHARS:
out.append('*' + ch)
prev_num = False
else: # ch in cls.OPCHARS
out.append(ch)
prev_num = False
else:
if ch in cls.NUMCHARS:
out.append(ch)
prev_num = True
elif ch in cls.VARCHARS:
out.append(ch)
# prev_num = False
else: # ch in cls.OPCHARS
out.append('**' if ch == '^' else ch)
# prev_num = False
return "".join(out)
def get_function(prompt, locals=None):
fn_str = input(prompt)
fn_str = FnStrCleaner.clean(fn_str)
return sympy.sympify(fn_str, locals=locals)
def main():
x = sympy.Symbol("x")
f = get_function("Enter f(x): ", {'x': x})
df = sympy.diff(f, x)
print("f(x) =", f)
print("f'(x) =", df)
if __name__ == "__main__":
main()
就像
Enter f(x): 29x^3 + 12x^2 - 9x + 5
f(x) = 29*x**3 + 12*x**2 - 9*x + 5
f'(x) = 87*x**2 + 24*x - 9
我把你的干净函数放在我的数学课上,因为这是一个有很多子类的类,所以我要清理很多fn_str,然后就是导数。但是,我不认为我能够访问它,因为它超出了我的派生类。我尝试只做数学。clean(fn_str),但我知道它缺少一个语法“fn_str”,所以我很困惑,它作为数学类的一部分应该可以很好地工作,只要(a)它仍然是一个类方法,(b)它可以访问NUMCHARS、VARCHARS、OPCHARS,勒加查尔斯。你能分享你当前的实际代码吗?hugh_bothwell在hotmail.com。。。尽管这看起来很像上面的第10条:没有理由让FnStrCleaner成为你数学课的一部分。为什么不保持原样呢?刚刚给你发了电子邮件,很抱歉搞砸了。所以我把你的干净函数放在我的数学课上,因为这是一个有很多子类的课,所以我会清理很多fn_str,然后就是导数。然而,我不认为我能够访问它,因为它超出了我的派生类。我试图只做数学清理(fn_str),但我知道它缺少一个绘图“fn_str”,所以我很困惑它应该可以作为p