符号化“<"在自定义函数中不返回布尔值? [英] Sympify &quot;&lt;&quot; does not return boolean in custom function?

查看:22
本文介绍了符号化“<"在自定义函数中不返回布尔值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结

我为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆