user7093850
user7093850

Reputation:

Comparing custom Fractions

I'm working through a book now and I have a question regarding one of exercises (#6). So we have a hand-made Fraction class and, besides all other kinds of things, we want to compare two fractions.

class Fraction:
    def __init__(self, num, den):
        if not (isinstance(num, int) and isinstance(den, int)):
            raise ValueError('Got non-int argument')
        if den == 0:
            raise ValueError('Got 0 denominator')
        self.num = num
        self.den = den

    # some class methods 

    def __lt__(self, other):
        selfnum = self.num * other.den
        othernum = other.num * self.den
        return selfnum < othernum

    # some class methods

# trying it out
x = Fraction(1, -2)
y = Fraction(1, 3)

However, when we evaluate x < y, the result is False. I thought of making new attribute to store sign, but that messes everything up quite a bit.

Due to lack of better alternative, I added if in the method, and here's what I got

def __lt__(self, other):
    selfnum = self.num * other.den
    othernum = other.num * self.den
    if self.den * other.den > 0:
        return selfnum < othernum
    else:
        return selfnum > othernum

Although it seems to be working, I wonder, if there is more elegant solution.

Update Storing sign in numerator does what I wanted (I can just change 2 lines instead of adding a conditional in each method).

Upvotes: 1

Views: 296

Answers (1)

Blender
Blender

Reputation: 298392

If you assume that both denominators are positive, you can safely do the comparison (since a/b < c/d would imply ad < bc). I would just store the sign in the numerator:

self.num = abs(num) * (1 if num / den > 0 else -1)
self.den = abs(den)

Or:

self.num = num
self.den = den

if self.den < 0:
    self.num = -self.num
    self.den = -self.den

And your __lt__ method can be:

def __lt__(self, other):
    return self.num * other.den < other.num * self.den

Upvotes: 2

Related Questions