分数类中的圆方法

时间:2015-03-02 14:23:25

标签: python

我正在构建一个分数类,而且我有一种方法无法正常运行。 我不完全确定这个函数应该如何工作,我需要帮助理解它。在代码的底部,我对每个函数进行了测试,并提供了所提供的信息,我想知道是否有人可以让我了解如何修复我的方法,以便类正常运行。

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

1 个答案:

答案 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

在您使用它的上下文中没有多大意义。