2013-07-19 13:11:40 +00:00
#!/usr/bin/env python
# encoding: utf-8
2014-02-21 05:01:34 +00:00
from . arithmetic import gcd
2013-07-19 13:11:40 +00:00
2014-02-27 17:02:34 +00:00
__all__ = [ ' Fraction ' ]
2013-07-19 13:11:40 +00:00
class Fraction ( object ) :
2013-08-07 23:12:11 +00:00
""" Fractions! """
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
def __init__ ( self , num , denom = 1 ) :
""" To initiate a fraction we need a numerator and a denominator
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
: param num : the numerator
: param denom : the denominator
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
"""
self . _num = num
self . _denom = denom
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
def simplify ( self ) :
""" Simplify the fraction
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
: returns : steps to simplify the fraction or the fraction if there is nothing to do
"""
2013-10-28 13:49:31 +00:00
steps = [ ]
2013-07-19 13:11:40 +00:00
2014-02-21 10:05:25 +00:00
if self . _num == 0 :
steps . append ( 0 )
return steps
2013-08-07 23:12:11 +00:00
if self . _denom < 0 :
2013-10-30 18:34:39 +00:00
n_frac = Fraction ( - self . _num , - self . _denom )
steps . append ( n_frac )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
gcd_ = gcd ( abs ( self . _num ) , abs ( self . _denom ) )
if self . _num == self . _denom :
2013-10-30 18:34:39 +00:00
n_frac = Fraction ( 1 , 1 )
steps . append ( n_frac )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
elif gcd_ != 1 :
2013-10-30 18:34:39 +00:00
n_frac = Fraction ( self . _num / / gcd_ , self . _denom / / gcd_ )
2013-11-16 19:50:42 +00:00
#steps.append("( {reste1} * {gcd} ) / ( {reste2} * {gcd} )".format(reste1 = n_frac._num, reste2 = n_frac._denom, gcd = gcd_))
steps . append ( [ n_frac . _num , gcd_ , ' * ' , n_frac . _denom , gcd_ , ' * ' , ' / ' ] )
2013-10-28 13:49:31 +00:00
# Certainement le truc le plus moche que j'ai jamais fait... On ne met que des strings dans steps puis au dernier moment on met une fraction. C'est moche de ma part
2013-10-30 18:34:39 +00:00
steps . append ( n_frac )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
return steps
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
def __str__ ( self ) :
if self . _denom == 1 :
return str ( self . _num )
else :
return str ( self . _num ) + " / " + str ( self . _denom )
2013-10-28 13:49:31 +00:00
def __repr__ ( self ) :
return " < Fraction " + self . __str__ ( ) + " > "
2014-02-21 10:08:55 +00:00
def __float__ ( self ) :
return self . _num / self . _denom
2013-08-07 23:12:11 +00:00
def __add__ ( self , other ) :
if type ( other ) == Fraction :
#cool
number = other
else :
number = Fraction ( other )
2013-07-19 13:11:40 +00:00
2013-10-28 13:49:31 +00:00
steps = [ ]
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
if self . _denom == number . _denom :
com_denom = self . _denom
num1 = self . _num
num2 = number . _num
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
else :
gcd_denom = gcd ( self . _denom , number . _denom )
coef1 = number . _denom / / gcd_denom
coef2 = self . _denom / / gcd_denom
2013-07-19 13:11:40 +00:00
2013-11-16 19:50:42 +00:00
steps . append ( [ self . _num , coef1 , " * " , self . _denom , coef1 , " * " , ' / ' , number . _num , coef2 , " * " , number . _denom , coef2 , " * " , " / " , ' + ' ] )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
com_denom = self . _denom * coef1
num1 = self . _num * coef1
num2 = number . _num * coef2
2013-07-19 13:11:40 +00:00
2013-11-16 19:50:42 +00:00
steps . append ( [ num1 , num2 , ' + ' , com_denom , ' / ' ] )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
num = num1 + num2
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
ans_frac = Fraction ( num , com_denom )
2013-10-28 13:49:31 +00:00
steps . append ( ans_frac )
2013-08-07 23:12:11 +00:00
steps + = ans_frac . simplify ( )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
return steps
2013-07-19 13:11:40 +00:00
2014-02-22 06:23:42 +00:00
def __radd__ ( self , other ) :
if type ( other ) == Fraction :
#cool
number = other
else :
number = Fraction ( other )
steps = [ ]
if number . _denom == self . _denom :
com_denom = number . _denom
num1 = number . _num
num2 = self . _num
else :
gcd_denom = gcd ( number . _denom , self . _denom )
coef1 = self . _denom / / gcd_denom
coef2 = number . _denom / / gcd_denom
steps . append ( [ number . _num , coef1 , " * " , number . _denom , coef1 , " * " , ' / ' , self . _num , coef2 , " * " , self . _denom , coef2 , " * " , " / " , ' + ' ] )
com_denom = number . _denom * coef1
num1 = number . _num * coef1
num2 = self . _num * coef2
steps . append ( [ num1 , num2 , ' + ' , com_denom , ' / ' ] )
num = num1 + num2
ans_frac = Fraction ( num , com_denom )
steps . append ( ans_frac )
steps + = ans_frac . simplify ( )
return steps
2013-08-07 23:12:11 +00:00
def __sub__ ( self , other ) :
if type ( other ) == Fraction :
#cool
number = other
else :
number = Fraction ( other )
2013-07-19 13:11:40 +00:00
2013-10-28 13:49:31 +00:00
steps = [ ]
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
if self . _denom == number . _denom :
com_denom = self . _denom
num1 = self . _num
num2 = number . _num
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
else :
gcd_denom = gcd ( self . _denom , number . _denom )
coef1 = number . _denom / / gcd_denom
coef2 = self . _denom / / gcd_denom
2013-07-19 13:11:40 +00:00
2013-11-16 19:50:42 +00:00
steps . append ( [ self . _num , coef1 , " * " , self . _denom , coef1 , " * " , ' / ' , number . _num , coef2 , " * " , number . _denom , coef2 , " * " , " / " , ' - ' ] )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
com_denom = self . _denom * coef1
num1 = self . _num * coef1
num2 = number . _num * coef2
2013-07-19 13:11:40 +00:00
2013-11-16 19:50:42 +00:00
steps . append ( [ num1 , num2 , ' - ' , com_denom , ' / ' ] )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
num = num1 - num2
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
ans_frac = Fraction ( num , com_denom )
2013-10-28 13:49:31 +00:00
steps . append ( ans_frac )
2013-08-07 23:12:11 +00:00
steps + = ans_frac . simplify ( )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
return steps
2014-01-17 17:10:38 +00:00
2014-02-22 06:23:42 +00:00
def __rsub__ ( self , other ) :
if type ( other ) == Fraction :
#cool
number = other
else :
number = Fraction ( other )
steps = [ ]
if number . _denom == self . _denom :
com_denom = number . _denom
num1 = number . _num
num2 = self . _num
else :
gcd_denom = gcd ( number . _denom , self . _denom )
coef1 = self . _denom / / gcd_denom
coef2 = number . _denom / / gcd_denom
steps . append ( [ number . _num , coef1 , " * " , number . _denom , coef1 , " * " , ' / ' , self . _num , coef2 , " * " , self . _denom , coef2 , " * " , " / " , ' - ' ] )
com_denom = number . _denom * coef1
num1 = number . _num * coef1
num2 = self . _num * coef2
steps . append ( [ num1 , num2 , ' - ' , com_denom , ' / ' ] )
num = num1 - num2
ans_frac = Fraction ( num , com_denom )
steps . append ( ans_frac )
steps + = ans_frac . simplify ( )
return steps
2014-01-17 17:10:38 +00:00
def __neg__ ( self ) :
return [ Fraction ( - self . _num , self . _denom ) ]
2013-08-07 23:12:11 +00:00
def __mul__ ( self , other ) :
if type ( other ) == Fraction :
#cool
number = other
else :
number = Fraction ( other )
2013-07-19 13:11:40 +00:00
2013-10-28 13:49:31 +00:00
steps = [ ]
2013-11-16 19:50:42 +00:00
steps . append ( [ self . _num , number . _num , ' * ' , self . _denom , number . _denom , ' * ' , ' / ' ] )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
num = self . _num * number . _num
denom = self . _denom * number . _denom
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
ans_frac = Fraction ( num , denom )
2013-10-28 13:49:31 +00:00
steps . append ( ans_frac )
2013-08-07 23:12:11 +00:00
steps + = ans_frac . simplify ( )
2013-07-19 13:11:40 +00:00
2013-08-07 23:12:11 +00:00
return steps
2013-07-19 13:11:40 +00:00
2014-02-22 06:23:42 +00:00
def __rmul__ ( self , other ) :
if type ( other ) == Fraction :
#cool
number = other
else :
number = Fraction ( other )
steps = [ ]
steps . append ( [ number . _num , self . _num , ' * ' , number . _denom , self . _denom , ' * ' , ' / ' ] )
num = self . _num * number . _num
denom = self . _denom * number . _denom
ans_frac = Fraction ( num , denom )
steps . append ( ans_frac )
steps + = ans_frac . simplify ( )
return steps
2013-08-07 23:12:11 +00:00
def __truediv__ ( self , other ) :
if type ( other ) == Fraction :
#cool
number = other
else :
number = Fraction ( other )
2013-07-19 13:11:40 +00:00
2013-10-28 13:49:31 +00:00
steps = [ ]
2013-08-07 23:12:11 +00:00
number = Fraction ( number . _denom , number . _num )
2014-02-22 06:23:42 +00:00
steps . append ( [ self , number , " / " ] )
2013-08-07 23:12:11 +00:00
steps + = self * number
return steps
2013-07-19 13:11:40 +00:00
2014-02-22 06:23:42 +00:00
def __rtruediv__ ( self , other ) :
if type ( other ) == Fraction :
#cool
number = other
else :
number = Fraction ( other )
steps = [ ]
self_inv = Fraction ( self . _denom , self . _num )
steps . append ( [ number , self_inv , " / " ] )
steps + = number * self_inv
return steps
2014-02-28 07:49:03 +00:00
def __abs__ ( self ) :
return Fraction ( abs ( self . _num ) , abs ( self . _denom ) )
2014-02-21 17:02:34 +00:00
def __eq__ ( self , other ) :
""" == """
if type ( other ) == Fraction :
number = other
else :
number = Fraction ( other )
return self . _num * number . _denom == self . _denom * number . _num
2013-10-28 13:49:31 +00:00
def __lt__ ( self , other ) :
2014-02-21 17:02:34 +00:00
""" < """
2013-10-28 13:49:31 +00:00
if type ( other ) == Fraction :
return ( self . _num / self . _denom ) < ( other . _num / other . _denom )
else :
return ( self . _num / self . _denom ) < other
def __le__ ( self , other ) :
2014-02-21 17:02:34 +00:00
""" <= """
2013-10-28 13:49:31 +00:00
if type ( other ) == Fraction :
return ( self . _num / self . _denom ) < = ( other . _num / other . _denom )
else :
return ( self . _num / self . _denom ) < = other
2013-07-19 13:11:40 +00:00
if __name__ == ' __main__ ' :
2013-10-28 13:49:31 +00:00
f = Fraction ( 1 , 12 )
g = Fraction ( 1 , 12 )
2014-02-22 09:13:12 +00:00
h = Fraction ( 1 , - 5 )
t = Fraction ( 4 , 5 )
2013-08-07 23:12:11 +00:00
print ( " --------- " )
2014-02-22 09:13:12 +00:00
for i in ( 1 + h ) :
2013-08-07 23:12:11 +00:00
print ( i )
print ( " --------- " )
2014-02-22 09:13:12 +00:00
#for i in (f + t):
# print(i)
#print("---------")
#for i in (f + g):
# print(i)
2013-10-28 13:49:31 +00:00
#print("---------")
#for i in (f - g):
# print(i)
#print("---------")
#for i in (f * g):
# print(i)
#print("---------")
#for i in (h + t):
# print(i)
#print("---------")
#for i in (h - t):
# print(i)
#print("---------")
#for i in (h * t):
# print(i)
#print("---------")
#for i in (h / t):
# print(i)
2013-08-07 23:12:11 +00:00
#print(f.simplify())
2013-07-19 13:11:40 +00:00
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del