gpt4 book ai didi

python - 如何(理智地)扩展 sympy.Rational

转载 作者:太空宇宙 更新时间:2023-11-04 03:17:02 24 4
gpt4 key购买 nike

有没有一种明智的方法可以在 sympy 中获取和使用 MixedNumbers 而不是假分数? (我正在使用 latex 输出并为小学生生成 pdf,如 1 3/4 + 2 1/3 =?)

我正在尝试创建一个用于 SymPy 的 MixedRational(或 MixedNumber 或 MixedFraction)类。 This是我能够找到的唯一与 SymPy 中的混合表示相关的线程。

我希望我的 MixedRational 类有 2 个成员变量:i 和 f,用于混合数的整数部分和小数部分,并有适当的方法,如 __str__ 以便它被打印为混合数数。

然而,我一直无法克服这条道路上的第一个障碍,即完全子类化 Rational 的能力。覆盖 __new__ 似乎是一个要求,因为 Rational.__new__(cls, *args) 返回它感觉的任何类型的实例,而不是返回类型 cls 的实例(为什么尝试 0 失败)。

我已经根据提供的参数创建了一个新的 Rational 并将其存储在 MixedNumber 中,并以某种方式透明地传递对 MixedNumber 未定义的函数和变量的访问(尝试 1、2、3),但我还没有使用我尝试过的任何方法都成功了。

因为我可以让 Rational 的子类在 Rational.__new__(cls, *args) 实际上返回 Rational(而不是 Integer 或 One 或 Zero)时正常运行,所以我几乎准备好了编写 5 个单独的类(MixedNumber、MixedRational、MixedInteger、MixedOne、MixedZero),使用 MixedNumber.__new__(cls, *args) 调用 Rational.__new__(cls, *args) 然后根据 Rational.__new__ 返回的类型决定实例化哪个 Mixed* 类。

但是,我觉得我必须将其复杂化。

from sympy import *
class MixedNumber(Rational):
def __new__(cls, *args):
#Attempt 3
rational_instance = Rational.__new__(cls, *args)
rational_instance.__class__ = cls
return rational_instance

#Attempt 2
#rational_instance = Rational.__new__(cls, *args)
#mixed_instance = object.__new__(cls)
#mixed_instance.my_rational = rational_instance
#print("dict")
#return mixed_instance

#Attempt 1
#rational_instance = Rational.__new__(cls, *args)
#mixed_instance = object.__new__(cls)
#mixed_instance.__dict__.update(rational_instance.__dict__)
#return mixed_instance

#Attempt 0
#return Rational.__new__(cls, *args)
def __init__(self, *args):
# print(self.__dict__)
# print(self.my_rational)
self.my_rational.__init__(*args)
#Attempt 2
#def __getattr__(self, attr):
# print("Attr=", attr)
# print("Dict=",self.__dict__)
# import time
# time.sleep(1)
# try:
# return self.__dict__[attr]
# except KeyError:
# return getattr(self.my_rational, attr)
x = Rational(0,1)
print(x)
print(type(x))
print(x.p)
print(x.q)
y = Rational(3,1)
print(y)
print(type(y))
print(y.p)
print(y.q)
z = Rational(15,4)
print(z)
print(type(z))
print(z.p)
print(z.q)
x = MixedNumber(0,1)
print(x)
print(type(x))
print(x.p)
print(x.q)
y = MixedNumber(3,1)
print(y)
print(type(y))
print(y.p)
print(y.q)
z = MixedNumber(15,4)
print(z)
print(type(z))
print(z.p)
print(z.q)

最佳答案

我认为尝试继承 Rational 是徒劳的。如此多的 SymPy 函数被硬编码为使用 Rational,即使您创建了一个成功的子类,您对表达式所做的任何事情都会将其再次移回 Rational

相反,您应该修改打印机,以便它按照您想要的方式打印内容。根据您使用的打印机,您应该子类化该打印机,并覆盖 _print_Rational。查看documentation .由于您提到了 latex ,因此您可以将 LatexPrinter 子类化并覆盖 _print_Rational(self, expr) 以不正确的形式打印 expr (有理数)。使用 self._print 递归打印子表达式。

然后您将使用 YourPrinter().doprint(expr) 来打印表达式,而不是默认的 latex(expr) (这是 LatexPrinter 的简写().doprint(expr)).

当对打印机进行子类化时,查看 original implementation 会很有用。 ( latex 打印机在 latex.py 中)。这是在撰写本文时 LatexPrinter._print_Rational 的默认实现

def _print_Rational(self, expr):
if expr.q != 1:
sign = ""
p = expr.p
if expr.p < 0:
sign = "- "
p = -p
return r"%s\frac{%d}{%d}" % (sign, p, expr.q)
else:
return self._print(expr.p)

关于python - 如何(理智地)扩展 sympy.Rational,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35871158/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com