其中一个练习是创建一个分数类,它可以采用负分母并仍能正确显示结果。然而,当我分开时,我仍然得到负输出:
class Fraction:
def __init__(self, num, denom):
if isinstance(num, int) or isinstance(denom, int):
common = gcd(num, abs(denom))
self._num = num//common
self._denom = abs(denom)//common
else:
raise TypeError
def __str__(self):
return "%d / %d" % (self._num, self._denom)
def __mul__(self, other):
denum = self._num * other._num
div = self._denom * other._denom
return Fraction(denum, div)
def __truediv__(self, other):
temp_fraction = Fraction(other._denom, other._num)
return self.__mul__(temp_fraction)
def gcd(a, b):
while(b):
a, b = b, a%b
return a
if __name__ == '__main__':
print(Fraction(-4, -5) / Fraction(-1, -2))
print(Fraction(-4, 5) / Fraction(-1, 2))
# Both output -8 / 5, should be 8 / 5
有人能告诉我我做错了吗?
编辑我已经纠正了我的代码,并在我的doctest中重写了一些错误的断言。现在所有测试都通过了!
完整代码:
from fractions import gcd
class Fraction:
"""
Checking if instantiating a fraction works
>>> print(Fraction(1, 2))
1 / 2
>>> print(Fraction(-1, 2))
-1 / 2
>>> print(Fraction('Foo', 'Bar'))
Traceback (most recent call last):
TypeError
Adding a fraction to another fraction
>>> print(Fraction(1, 2) + Fraction(1, 4))
3 / 4
>>> print(Fraction(-1, 2) + Fraction(2, 2))
1 / 2
>>> print(Fraction(-1, 5) + Fraction(-1, 5))
-2 / 5
>>> print(Fraction(-1, -5) + Fraction(-1, -5))
2 / 5
Substracting a fraction from another
>>> print(Fraction(3, 4) - Fraction(1, 4))
1 / 2
>>> print(Fraction(-1, 2) - Fraction(1, 4))
-3 / 4
>>> print(Fraction(-2, 10) - Fraction(-1, 10))
-1 / 10
>>> print(Fraction(-2, -10) - Fraction(-1, -10))
1 / 10
Multiplying 2 fractions
>>> print(Fraction(1, 5) * Fraction(1, 2))
1 / 10
>>> print(Fraction(-1, 2) * Fraction(1, 4))
-1 / 8
>>> print(Fraction(-1, 2) * Fraction(-1, 8))
1 / 16
>>> print(Fraction(-1, -2) * Fraction(-1, -8))
1 / 16
Dividing 2 fractions
>>> print(Fraction(1, 4) / Fraction(1, 2))
1 / 2
>>> print(Fraction(-1, 2) / Fraction(1, 15))
-15 / 2
>>> print(Fraction(-4, 5) / Fraction(-1, 2))
8 / 5
>>> print(Fraction(-4, -5) / Fraction(-1, -2))
8 / 5
Equality between fractions
>>> print(Fraction(1, 2) == Fraction(2, 4))
True
>>> print(Fraction(1, 2) == Fraction(1, 3))
False
>>> print(Fraction(-2, 4) == Fraction(-1, 2))
True
>>> print(Fraction(-2, -4) == Fraction(-1, -2))
True
Non-equality between fractions
>>> print(Fraction(1, 2) != Fraction(64, 128))
False
>>> print(Fraction(1, 4) != Fraction(999, 4000))
True
>>> print(Fraction(-3, 4) != Fraction(-3, 5))
True
>>> print(Fraction(-3, -4) != Fraction(-3, -5))
True
Larger size difference between fractions
>>> print(Fraction(1, 2) > Fraction(857, 1713))
False
>>> print(Fraction(1, 2) > Fraction(857, 1715))
True
>>> print(Fraction(1, 338) >= Fraction(2, 676))
True
>>> print(Fraction(-2, 5) > Fraction(-1, 5))
False
>>> print(Fraction(-2, -5) > Fraction(-1, -5))
True
Smaller size difference between fractions
>>> print(Fraction(1, 2) < Fraction(857, 1713))
True
>>> print(Fraction(1, 2) < Fraction(857, 1715))
False
>>> print(Fraction(1, 338) <= Fraction(2, 676))
True
>>> print(Fraction(-3, 7) < Fraction(-6, 7))
False
>>> print(Fraction(-3, -7) < Fraction(-6, -7))
True
"""
def __init__(self, num, denom):
if isinstance(num, int) and isinstance(denom, int):
common = gcd(num, denom)
self._num = num//common
self._denom = denom//common
else:
raise TypeError
def __str__(self):
return "%d / %d" % (self._num, self._denom)
def __add__(self, other):
denum = (self._num * other.get_denom()) + (other.get_num() * self._denom)
div = (self._denom * other.get_denom())
return Fraction(denum, div)
def __sub__(self, other):
denum = (self._num * other.get_denom()) - (other.get_num() * self._denom)
div = (self._denom * other.get_denom())
return Fraction(denum, div)
def __mul__(self, other):
denum = self._num * other.get_num()
div = self._denom * other.get_denom()
return Fraction(denum, div)
def __truediv__(self, other):
temp_fraction = Fraction(other.get_denom(), other.get_num())
return self.__mul__(temp_fraction)
def eq_denum(self, other):
first = self._num * other.get_denom()
last = other.get_num() * self._denom
return first, last
def __eq__(self, other):
first, last = self.eq_denum(other)
return first == last
def __ne__(self, other):
first, last = self.eq_denum(other)
return first != last
def __gt__(self, other):
first, last = self.eq_denum(other)
return first > last
def __ge__(self, other):
first, last = self.eq_denum(other)
return first >= last
def __lt__(self, other):
first, last = self.eq_denum(other)
return first < last
def __le__(self, other):
first, last = self.eq_denum(other)
return first <= last
def get_num(self):
return self._num
def get_denom(self):
return self._denom
if __name__ == '__main__':
import doctest
doctest.testmod()
答案 0 :(得分:1)
问题不在于除法,而是在gcd
中使用__init__
函数的方式。
在创建分数时,您似乎只需要删除所有abs
。这样,如果gcd
为否定,则denom
将为否定,并且您会获得所需的行为。
if isinstance(num, int) and isinstance(denom, int):
common = gcd(num, denom)
self._num = num//common
self._denom = denom//common
一些例子:
# with abs # without abs
print(Fraction( 4, 6)) # 2/3 2/3
print(Fraction( 4, -6)) # 2/3 -2/3
print(Fraction(-4, 6)) # -2/3 -2/3
print(Fraction(-4, -6)) # -2/3 2/3
另请注意,两个数字应该是整数,而不仅仅是其中一个(使用and
)。
答案 1 :(得分:-2)
只需将 __ str __ 更改为:
return "%d / %d" % (abs(self._num), abs(self._denom))