符号化“<"在自定义函数中不返回布尔值? [英] Sympify "<" does not return boolean in custom function?
问题描述
总结
我为 sympy 自写的 if-then-else 条件对某些布尔值不起作用.
代码(注意:分段不是我的选择,这里建议 https://stackoverflow.com/a/38858444/5626139)
from sympy import 函数类 ifte(功能):参数 = 3@类方法def eval(cls, a, b, c):如果 a >0:返回 b别的:返回 c
部分工作,例如使用这三个布尔值:
<预><代码>>>>print(ifte('1+2 and True and 1 != 2', 'b', 'c'))乙问题
为什么 0<1 的行计算正确?
<预><代码>>>>打印(ifte('0==1','b','c'))乙>>>打印(ifte('0<1', 'b', 'c'))类型错误:布尔参数只能在 Eq 和 Ne 中使用;所有其他关系期望真正的表达.if 条件中的所有运算符通常计算为布尔值.
- 为什么这不适用于 <, >, <=, >= ?
- 有什么解决办法吗?
- 我如何确定其他语句是否也最终成为异常?
问题是在if
时触发的:
from sympy import 函数类 ifte(功能):参数 = 3@类方法def eval(cls, a, b, c):如果 a >0: # <-- 这里的问题返回 b别的:返回 c
并且与a
得到的type
有关.由于这取决于 a
中的表达式,您会观察到不同表达式的不同行为.特别是,对于 a
的某些值,这变成了 sympy.logic.boolalg.*
.如果是这种情况,则 __gt__
方法(在使用 >
运算符时调用)未定义,并且您会看到您观察到的错误.对于其他一些值,这将是一个简单的 bool
,为此定义了 __gt__
方法,并且代码按照您期望的方式工作.
要解决此问题,只需删除 >0
比较,即
from sympy import 函数类 ifte(功能):参数 = 3@类方法def eval(cls, a, b, c):如果一个:返回 b别的:返回 c
或者,更简单:
from sympy import 函数类 ifte(功能):参数 = 3@类方法def eval(cls, a, b, c):返回 b if a else c
print(ifte('1+2 and True and 1 != 2', 'b', 'c'))# 乙打印(ifte('1==0','b','c'))# C打印(ifte('1> 0','b','c'))# 乙打印(ifte('1<0', 'b', 'c'))# C
请注意,您收到的错误消息在一定程度上取决于您拥有的 SymPy 版本,但原理是相同的.例如,在版本 1.1.1
中,我得到:
类型错误:BooleanTrue"和int"的实例之间不支持>"
Summary
My self-written if-then-else conditional for sympy does not work for some Booleans.
Code (Note: Piecewise is not an option for me, proposed here https://stackoverflow.com/a/38858444/5626139)
from sympy import Function
class ifte(Function):
nargs = 3
@classmethod
def eval(cls, a, b, c):
if a > 0:
return b
else:
return c
Which works partially, for example with these three booleans:
>>> print(ifte('1+2 and True and 1 != 2', 'b', 'c'))
b
Problem
Why does the line with 0<1 evaluate correctly?
>>> print(ifte('0==1', 'b', 'c'))
b
>>> print(ifte('0<1', 'b', 'c'))
TypeError:
A Boolean argument can only be used in Eq and Ne; all other
relationals expect real expressions.
All the operators in the if-condition usually evaluate to boolean.
- Why does this not work for <, >, <=, >= ?
- Is there a solution to this?
- How can I be sure if other statements also end up as exception?
The issue is triggered during the if
:
from sympy import Function
class ifte(Function):
nargs = 3
@classmethod
def eval(cls, a, b, c):
if a > 0: # <-- PROBLEM HERE
return b
else:
return c
and it is related to the type
that a
gets.
Since this depends on the expression in a
, you observe different behaviors for different expression.
In particular, for some values of a
, this gets to be sympy.logic.boolalg.*
.
If that is the case, then the __gt__
method (which is called when the >
operator is used) is not defined and you get the error you observe.
For some other values, this gets to be a simple bool
, for which the __gt__
method is defined and the code works the way you expect.
To solve the issue, simply remove the > 0
comparison, i.e.
from sympy import Function
class ifte(Function):
nargs = 3
@classmethod
def eval(cls, a, b, c):
if a:
return b
else:
return c
or, even more simply:
from sympy import Function
class ifte(Function):
nargs = 3
@classmethod
def eval(cls, a, b, c):
return b if a else c
print(ifte('1+2 and True and 1 != 2', 'b', 'c'))
# b
print(ifte('1==0', 'b', 'c'))
# c
print(ifte('1>0', 'b', 'c'))
# b
print(ifte('1<0', 'b', 'c'))
# c
Note that the error message you get depends a bit on the SymPy version you have, but the principle is the same.
For example, in version 1.1.1
I get:
TypeError: '>' not supported between instances of 'BooleanTrue' and 'int'
这篇关于符号化“<"在自定义函数中不返回布尔值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!