使用 类 减法时如何 return 负分数?
How to return a negative fraction when subtracting with use of classes?
在我的部分代码中,我可以减去分数,但是如果我输入 (- p),其中 p 是分数,我会得到 TypeError: unsupported operand type(s) for +: "Fraction" and "Fraction"
def gcd(denominator, numerator):
if numerator == 0:
return denominator
else:
return gcd(numerator, (denominator % numerator))
class Fraction:
def __init__(self,numerator = 0, denominator = 1):
self.numerator = int(numerator / gcd(abs(denominator),abs(numerator) ))
self.denominator = int(denominator / gcd(abs(denominator),abs(numerator) ))
if self.denominator < 0:
self.denominator = abs(self.denominator)
self.numerator = -1*self.numerator
elif self.denominator == 0:
raise ZeroDivisionError
def __str__(self):
if self.denominator == 1:
return str(self.numerator)
else:
return str(self.numerator) + "/" + str(self.denominator)
def __rsub__(self,other):
return self.__sub__(other)
def __sub__(self,other):
if type(other) == int:
other = Fraction(other,1)
return self.sub(other)
else:
return self.sub(other)
def sub(self,other):
result = Fraction()
result.numerator = other.denominator * self.numerator - self.denominator * other.numerator
result.denominator = other.denominator * self.denominator
multiple = gcd(result.denominator,result.numerator)
result.numerator = int(result.numerator / multiple)
result.denominator = int(result.denominator / multiple)
return result
p = Fraction(2,3)
r = (- p)
但是,当我的输入是 (1 - p) 时,我得到了正确的输出。假设 p = Fraction(2, 3) 那么我想 (- p) 到 return (-2 / 3) 或 (2/ -3)。在我看来,问题在于减法时没有为第一个参数提供输入。在搜索时我确实遇到了 __neg__
之类的东西,但我对 python 和使用 类 还是个新手,所以我不知道如何实现它。有谁知道我该如何解决这个问题?
提前致谢!
你的__rsub__
代码被翻转了,你想要other.__sub__(self)
。
def __rsub__(self,other):
return other.__sub__(self)
你是对的;您需要实施 __neg__
因为减号不是(二元)减法运算符,而是一元减号。
这里是你如何做到的:
def __neg__(self):
return Fraction(-self.numerator, self.denominator)
其他问题
__rsub__
您需要更改 __rsub__
的实现,因为当 other
不支持 __sub__
时将调用该方法。例如,当你评估这个时它会启动:
p = 1 - Fraction(2, 3)
该评估将无法按目前的情况进行。你需要有这个:
def __rsub__(self, other):
return Fraction(other) - self
或者,显式调用 __sub__
:
def __rsub__(self, other):
return Fraction(other).__sub__(self)
规范化
构造函数正确地归一化分数,确保分母为正,但您在 sub
方法中不这样做。那里的结果可能没有标准化:分母可能保持负数。
另外,很遗憾,你复制了构造函数中已有的gcd相关代码。最好依靠构造函数来实现该逻辑。
不变性
最好将实例视为不可变的。所以你不应该在构造函数之外对 instance.numerator
和 instance.denominator
进行任何赋值。确保首先确定分子和分母(没有规范化),然后然后调用构造函数将它们作为参数传递。
比较
您可能想要比较分数的相等性或相对顺序。为此,您可以实施 __eq__
、__lt__
、...等
建议代码
以下是我的做法:
def gcd(denominator, numerator):
if numerator == 0:
return denominator
else:
return gcd(numerator, denominator % numerator)
class Fraction:
def __new__(cls, numerator=0, denominator=1):
if isinstance(numerator, Fraction):
return numerator # Use this instance and ignore 2nd argument
return super(Fraction, cls).__new__(cls)
def __init__(self, numerator=0, denominator=1):
if isinstance(numerator, Fraction):
return # self is already initialised by __new__
if denominator == 0:
raise ZeroDivisionError
div = gcd(abs(denominator), abs(numerator))
if denominator < 0:
div = -div
self.numerator = numerator // div
self.denominator = denominator // div
def __str__(self):
if self.denominator == 1:
return str(self.numerator)
else:
return f"{self.numerator}/{self.denominator}"
def __rsub__(self, other):
return Fraction(other) - self
def __sub__(self, other):
other = Fraction(other)
return Fraction(other.denominator * self.numerator
- self.denominator * other.numerator,
other.denominator * self.denominator)
def __neg__(self):
return Fraction(-self.numerator, self.denominator)
def __eq__(self, other):
other = Fraction(other)
return (self.numerator == other.numerator and
self.denominator == other.denominator)
def __lt__(self, other):
other = Fraction(other)
return (other.denominator * self.numerator <
self.denominator * other.numerator)
def __gt__(self, other):
return Fraction(other) < self
def __le__(self, other):
return self < other or self == other
def __ge__(self, other):
return self > other or self == other
在我的部分代码中,我可以减去分数,但是如果我输入 (- p),其中 p 是分数,我会得到 TypeError: unsupported operand type(s) for +: "Fraction" and "Fraction"
def gcd(denominator, numerator):
if numerator == 0:
return denominator
else:
return gcd(numerator, (denominator % numerator))
class Fraction:
def __init__(self,numerator = 0, denominator = 1):
self.numerator = int(numerator / gcd(abs(denominator),abs(numerator) ))
self.denominator = int(denominator / gcd(abs(denominator),abs(numerator) ))
if self.denominator < 0:
self.denominator = abs(self.denominator)
self.numerator = -1*self.numerator
elif self.denominator == 0:
raise ZeroDivisionError
def __str__(self):
if self.denominator == 1:
return str(self.numerator)
else:
return str(self.numerator) + "/" + str(self.denominator)
def __rsub__(self,other):
return self.__sub__(other)
def __sub__(self,other):
if type(other) == int:
other = Fraction(other,1)
return self.sub(other)
else:
return self.sub(other)
def sub(self,other):
result = Fraction()
result.numerator = other.denominator * self.numerator - self.denominator * other.numerator
result.denominator = other.denominator * self.denominator
multiple = gcd(result.denominator,result.numerator)
result.numerator = int(result.numerator / multiple)
result.denominator = int(result.denominator / multiple)
return result
p = Fraction(2,3)
r = (- p)
但是,当我的输入是 (1 - p) 时,我得到了正确的输出。假设 p = Fraction(2, 3) 那么我想 (- p) 到 return (-2 / 3) 或 (2/ -3)。在我看来,问题在于减法时没有为第一个参数提供输入。在搜索时我确实遇到了 __neg__
之类的东西,但我对 python 和使用 类 还是个新手,所以我不知道如何实现它。有谁知道我该如何解决这个问题?
提前致谢!
你的__rsub__
代码被翻转了,你想要other.__sub__(self)
。
def __rsub__(self,other):
return other.__sub__(self)
你是对的;您需要实施 __neg__
因为减号不是(二元)减法运算符,而是一元减号。
这里是你如何做到的:
def __neg__(self):
return Fraction(-self.numerator, self.denominator)
其他问题
__rsub__
您需要更改 __rsub__
的实现,因为当 other
不支持 __sub__
时将调用该方法。例如,当你评估这个时它会启动:
p = 1 - Fraction(2, 3)
该评估将无法按目前的情况进行。你需要有这个:
def __rsub__(self, other):
return Fraction(other) - self
或者,显式调用 __sub__
:
def __rsub__(self, other):
return Fraction(other).__sub__(self)
规范化
构造函数正确地归一化分数,确保分母为正,但您在 sub
方法中不这样做。那里的结果可能没有标准化:分母可能保持负数。
另外,很遗憾,你复制了构造函数中已有的gcd相关代码。最好依靠构造函数来实现该逻辑。
不变性
最好将实例视为不可变的。所以你不应该在构造函数之外对 instance.numerator
和 instance.denominator
进行任何赋值。确保首先确定分子和分母(没有规范化),然后然后调用构造函数将它们作为参数传递。
比较
您可能想要比较分数的相等性或相对顺序。为此,您可以实施 __eq__
、__lt__
、...等
建议代码
以下是我的做法:
def gcd(denominator, numerator):
if numerator == 0:
return denominator
else:
return gcd(numerator, denominator % numerator)
class Fraction:
def __new__(cls, numerator=0, denominator=1):
if isinstance(numerator, Fraction):
return numerator # Use this instance and ignore 2nd argument
return super(Fraction, cls).__new__(cls)
def __init__(self, numerator=0, denominator=1):
if isinstance(numerator, Fraction):
return # self is already initialised by __new__
if denominator == 0:
raise ZeroDivisionError
div = gcd(abs(denominator), abs(numerator))
if denominator < 0:
div = -div
self.numerator = numerator // div
self.denominator = denominator // div
def __str__(self):
if self.denominator == 1:
return str(self.numerator)
else:
return f"{self.numerator}/{self.denominator}"
def __rsub__(self, other):
return Fraction(other) - self
def __sub__(self, other):
other = Fraction(other)
return Fraction(other.denominator * self.numerator
- self.denominator * other.numerator,
other.denominator * self.denominator)
def __neg__(self):
return Fraction(-self.numerator, self.denominator)
def __eq__(self, other):
other = Fraction(other)
return (self.numerator == other.numerator and
self.denominator == other.denominator)
def __lt__(self, other):
other = Fraction(other)
return (other.denominator * self.numerator <
self.denominator * other.numerator)
def __gt__(self, other):
return Fraction(other) < self
def __le__(self, other):
return self < other or self == other
def __ge__(self, other):
return self > other or self == other