Basil - 2 months ago 21

Python Question

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 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`

`False`

Due to lack of better alternative, I added

`if`

`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.

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

Answer

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
```