我正在构建一个分数类,而且我有一种方法无法正常运行。 我不完全确定这个函数应该如何工作,我需要帮助理解它。在代码的底部,我对每个函数进行了测试,并提供了所提供的信息,我想知道是否有人可以让我了解如何修复我的方法,以便类正常运行。
import math
#This class will be able to create fraction objects and will allow you do to regular perform regular math on it such as divsion, subtraction, multiplication, division,
#And things such as power
class Fraction:
def __init__(self,numerator=0,denominator=1):
'''
Initializes the Fraction to the numerator and denominator
values provided by the constructor.
numerator - value of numerator with a default value of 0.
The type must be of integer.
denomenator - value of denomenator with a default value of 1.
The type must be of integer.
'''
if not isinstance(denominator,int):
raise TypeError("denominator must be of type int!")
if not isinstance(numerator,int):
raise TypeError("numerator must be of type int!")
if denominator == 0:
raise ZeroDivisionError("Denominator cannot be 0")
self.numer = numerator
self.denom = denominator
self.normalize()
def __str__(self):
s = "%d /% d" % (self.numer,self.denom)
return s
def normalize(self):
reduce = Fraction.gcd(self.numer, self.denom)
self.numer = self.numer // reduce
self.denom = self.denom // reduce
#When testing the GCD of a certain fraction create a new one like (x = Fraction) with no parameters. Then invoke the method with (x.gcd(a,b))..
#This will find the greatest common denominator
def gcd(a,b):
while b:
a, b = b, a%b
return a
# necessary to define so that it is usable on hashable
# collections like set, dict, etc..
def __hash__(self):
'''' returns the hash of the fraction equivalent to
the hash of the floating point number the fraction represents.
'''
return hash(self.numer/self.denom) # use hash of floating point equiv.
# comparison operators
def __lt__(self,other):
''' returns True if this fraction is less than the other
fraction, false otherwise.
'''
if isinstance(other,int):
other = Fraction(other, self.denom)
return self.numer*other.denom < other.numer*self.denom
elif isinstance(other,float):
return float(self) < other
return self.numer*other.denom < other.numer*self.denom
#Returns true if fracrion is less or equal to other fraction and false otherwise
def __le__(self,other):
''' returns True if this fraction is less than or equal
to the other fraction, false otherwise.
'''
if isinstance(other,int):
other = Fraction(other, self.denom)
return self.numer*other.denom <= other.numer*self.denom
elif isinstance(other,float):
return float(self) <= other
return self.numer*other.denom <= other.numer*self.denom
#Tests if one fraction is equal to the other
def __eq__(self, other):
if not isinstance(other,Fraction):
return int(self) == other
return self.numer*other.denom == other.numer*self.denom
#Tests if on fraction is not equal to the other
def __ne__(self, other):
if not isinstance(other,Fraction):
return int(self) != other
return self.numer*other.denom != other.numer*self.denom
#Return true if fraction is greater than other fraction.. If not it will return false
def __gt__(self, other):
if not isinstance(other,Fraction):
other = int(other)
other = Fraction(other, self.denom)
return self.numer*other.denom > other.numer*self.denom
return self.numer*other.denom > other.numer*self.denom
#Returns true if the fraction is less than or equal to fraction and false if it is not
def __ge__(self, other):
if not isinstance(other,Fraction):
other = int(other)
other = Fraction(other, self.denom)
return self.numer*other.denom >= other.numer*self.denom
return self.numer*other.denom >= other.numer*self.denom
#Arithmetic operators
#this is the addition operator
def __add__(self, other):
''' returns an instance of a Fraction that represents the sum
of the fraction reprsented by self and other.
'''
if isinstance(other,int):
return Fraction(self.numer + other*self.denom, self.denom)
elif isinstance(other,float):
return Fraction(self.numer + int(other)*self.denom, self.denom)
elif isinstance(other,Fraction):
return Fraction(self.numer*other.denom+other.numer*self.denom, self.denom*other.denom)
else:
return NotImplemented
#Multiplication and division operators
def __sub__(self, other):
if isinstance(other,int):
return Fraction(self.numer-other*self.denom, self.denom)
elif isinstance(other,float):
return Fraction(int(self.numer-other*self.denom), self.denom)
elif isinstance(other,Fraction):
return Fraction(other.denom*self.numer-self.denom*other.numer, self.denom*other.denom)
else:
return NotImplemented
#Multiplication operator
def __mul__(self, other):
if isinstance(other, int):
return Fraction(self.numer*other, self.denom)
elif isinstance(other, float):
return Fraction(int(self.numer*other), self.denom)
elif isinstance(other, Fraction):
return Fraction(self.numer*other.numer, self.denom*other.denom)
else:
return NotImplemented
#Division operator
def __truediv__(self, other):
if isinstance(other, int):
return Fraction(self.numer, self.denom*other)
elif isinstance(other, float):
return Fraction(int(self.numer), int(self.denom*other))
elif isinstance(other, Fraction):
return Fraction(self.numer*other.denom, self.denom*other.numer)
else:
return NotImplemented
#This is the power operator... It will raise both numer and denom to the power
def __pow__(self, other):
if isinstance(other, int):
return Fraction(self.numer ** other, self.denom ** other)
elif isinstance(other, float):
return Fraction(int(self.numer ** other), int(self.denom ** other))
elif isinstance(other, Fraction):
return Fraction(self.numer ** int(other.numer/other.denom), self.denom ** int(other.numer/other.denom))
# reflected swapped operands
def __radd__(self, other):
if isinstance(other,int):
return Fraction(self.numer + other *self.denom, self.denom)
elif isinstance(other,float):
return Fraction(self.numer + int(other)*self.denom, self.denom)
return self + Fraction(other,1)
#These methods are called if their counterparts don't exist
def __rsub__(self, other):
if isinstance(other,int):
return Fraction(other*self.denom-self.numer , self.denom)
elif isinstance(other,float):
return Fraction(int(other*self.denom-self.numer), self.denom)
elif isinstance(other,Fraction):
return Fraction(other,1)- self
else:
return NotImplemented
def __rmul__(self, other):
if isinstance(other, int):
return Fraction(self.numer*other, self.denom)
elif isinstance(other, float):
return Fraction(int(self.numer*other), self.denom)
return self * Fraction(other,1)
def __rtruediv__(self, other):
if isinstance(other,int):
return Fraction(self.denom*other, self.numer)
elif isinstance(other, float):
return Fraction(int(self.denom*other), self.numer)
return self / Fraction(other,1)
def __rpow__(self, other):
if isinstance(other, int):
return Fraction(int(other ** (self.numer/self.denom)), int(other ** (self.numer/self.denom)))
elif isinstance(other, float):
return Fraction(int(other ** (self.numer/self.denom)), int(other ** (self.numer/self.denom)))
elif isinstance(other, Fraction):
return Fraction(self.numer ** int(other.numer/other.denom), self.denom ** int(other.numer/other.denom))
return self ** Fraction(other,1)
# augmented operators
def __iadd__(self, other):
''' returns an instance of a Fraction that represents the sum
of the fraction reprsented by self and other. This new instance
becomes the new self.
'''
# Use the fact that the __add__ method
# takes care of all all cases.
#
# return the new Fraction object. This becomes
# the new self!
return self + other
#This is the augment for subtraction
def __isub__(self, other):
return self - other
#This is the augment for multiplication
def __imul__(self, other):
return self * other
#This is the augment for Division
def __itruediv__(self, other):
return self / other
#All of these methods below are COMPLETE
# unary operators and absolute value
#This will cause the fraction to be negative
def __neg__(self):
return Fraction(-self.numer, self.denom)
#This will cause the fractions to be positive
def __pos__(self):
return Fraction(+self.numer, self.denom)
#This will calculate the absolute value of the fraction
def __abs__(self):
return Fraction(abs(self.numer),abs(self.denom))
# converting and rounding off
#This will turn the fraction into an integer
def __int__(self):
value = self.numer/self.denom
value = math.floor(value)
return value
#This will turn the fraction into a float type
def __float__(self):
floatValue = self.numer/self.denom
return floatValue
#This will round the fraction down to a single int with the ceiling function
def __round__(self, n=0):
n = self.numer/self.denom
n = math.ceil(n)
return n
if __name__ == "__main__":
import copy
a = Fraction(8,32)
assert a == Fraction(1,4)
b = Fraction(2,-16)
assert b == Fraction(-1,8)
# comparison operators
assert (a < b) == False
assert b < a
assert(a < 0) == False
assert a < 2
assert a < 2.0
assert (a <= b) == False
assert b <= a
assert a <= a
assert (a <= 0) == False
assert a <= 2
assert a <= 2.0
assert a > b
assert (b > a) == False
assert a > 0
assert (a > 2) == False
assert (a > 2.0) == False
assert a >= b
assert (b >= a) == False
assert a >= a
assert a >= 0
assert (a >= 2) == False
assert (a >= 2.0) == False
assert (a == b) == False
assert b == b
assert a == a
assert a != b
assert (b != b) == False
# addition
assert a+2 == Fraction(9,4)
assert 2+a == Fraction(9,4)
assert a > 0.0001
assert abs((a+2.0)-(9/4)) < 0.0001
assert abs((2.0+a)-(9/4)) < 0.0001
assert a+b == Fraction(1,8)
assert a+Fraction(1,3) == Fraction(7,12)
# subtraction
assert a-2 == Fraction(-7,4)
assert 2-a == Fraction(7,4)
assert abs((a-2.0)-(-7/4)) < 0.0001
assert abs((2.0-a)-(7/4)) < 0.0001
assert a-b == Fraction(3,8)
assert b-a == Fraction(-3,8)
assert a-Fraction(1,3) == Fraction(-1,12)
# multiplication
assert a*2 == Fraction(1,2)
assert 2*a == Fraction(1,2)
assert abs((a*2.0)-(1/2)) < 0.0001
assert abs((2.0*a)-(1/2)) < 0.0001
assert a*b == Fraction(-1,32)
# division
assert a/2 == Fraction(1,8)
assert 2/a == Fraction(8,1)
assert abs((a/2.0)-(1/8)) < 0.0001
assert abs((2.0/a)-8.0) < 0.0001
assert abs(a/b - (-2.0)) < 0.0001
# power
assert a**2 == Fraction(1,16)
assert abs(2**a - 2**(1/4)) < 0.0001
assert abs((a**2.0)-(1/4)**2.0) < 0.0001
assert abs((2.0**a)-2.0**(1/4)) < 0.0001
assert abs(a**b - (1/4)**(-1/8)) < 0.0001
# += operator
c = copy.copy(a)
c += 2
assert c == Fraction(9,4)
c = copy.copy(a)
c += 2.0
assert abs(c -(9/4)) < 0.0001
c = copy.copy(a)
c += b
assert c == Fraction(1,8)
c = copy.copy(a)
c += Fraction(1,3)
assert c == Fraction(7,12)
# -= operator
c = copy.copy(a)
c -= 2
assert c == Fraction(-7,4)
c = copy.copy(a)
c -= 2.0
assert abs((c)-(-7/4)) < 0.0001
c = copy.copy(a)
c -= b
assert c == Fraction(3,8)
c = copy.copy(a)
c -= Fraction(1,3)
assert c == Fraction(-1,12)
# *= operator
c = copy.copy(a)
c *= 2
assert c == Fraction(1,2)
c = copy.copy(a)
c *= 2.0
assert abs((a*2.0)-(1/2)) < 0.0001
c = copy.copy(a)
c *= b
assert c == Fraction(-1,32)
# /= operator
c = copy.copy(a)
c /= 2
assert c == Fraction(1,8)
c = copy.copy(a)
c /= 2.0
assert abs(c -(1/8)) < 0.0001
c = copy.copy(a)
c /= b
assert abs(c - (-2.0)) < 0.0001
# -a, +a , |a|
assert -a == Fraction(-1,4)
assert -b == Fraction(1,8)
assert +a == a
assert abs(b) == Fraction(1,8)
# int, float, round
assert int(Fraction(4,3)) == 1
assert int(Fraction(3,4)) == 0
#Could not get these to work.
assert abs(float(a)-(1/4)) < 0.0001
assert abs(float(b)-(-1/8)) < 0.0001
assert abs(round(b,2)- (-.12)) < 0.0001
assert abs(round(b,1)- (-.1)) < 0.0001
答案 0 :(得分:0)
您的问题与您对round
功能的定义有关。大概你需要:
#This will round the fraction down to a single int with the ceiling function
def __round__(self, n=0):
return round(self.numer/self.denom, n)
而不是
def __round__(self, n=0):
n = self.numer/self.denom
n = math.ceil(n)
return n
在您使用它的上下文中没有多大意义。