Add 2 fractions works!

This commit is contained in:
Bertrand Benjamin 2018-03-12 07:34:26 +03:00
parent 5f5fcc5a79
commit 98381f4512
4 changed files with 204 additions and 18 deletions

View File

@ -46,6 +46,24 @@ class MOFraction(MO):
self._denominator = denominator self._denominator = denominator
self.negative = negative self.negative = negative
@property
def numerator(self):
""" Get the numerator. If self is negative, getting the opposite of the _numerator
"""
if self.negative:
return Tree("-", None, self._numerator)
return self._numerator
@property
def denominator(self):
return self._denominator
def inverse(self):
""" return the inverse fraction """
return MOFraction(self._denominator,
self._numerator,
self.negative)
# ----------------------------- # -----------------------------
# Reglages pour 'vim' # Reglages pour 'vim'

View File

@ -15,6 +15,7 @@ from ..operator import OPERATORS
from ..MO.mo import MO, MOnumber, MOstr from ..MO.mo import MO, MOnumber, MOstr
from ..MO.fraction import MOFraction from ..MO.fraction import MOFraction
from .exceptions import AddError from .exceptions import AddError
from .arithmetic import lcm
def add(left, right): def add(left, right):
@ -106,11 +107,109 @@ def mofraction_monumber(left, right):
right_fraction = MOFraction(right, MOnumber(1)) right_fraction = MOFraction(right, MOnumber(1))
return Tree("+", left, right_fraction) return Tree("+", left, right_fraction)
def mofraction_mofraction(left, right):
""" Adding two mofractions
:param left: a mofraction
:param right: a mofraction
:returns: Tree
>>> a = MOFraction(1, 5)
>>> b = MOFraction(4, 5)
>>> print(mofraction_mofraction(a, b))
/
> +
| > 1
| > 4
> 5
>>> a = MOFraction(1, 5, True)
>>> b = MOFraction(4, 5)
>>> print(mofraction_mofraction(a, b))
/
> +
| > -
| | > None
| | > 1
| > 4
> 5
>>> a = MOFraction(1, 5)
>>> b = MOFraction(4, 5, True)
>>> print(mofraction_mofraction(a, b))
/
> +
| > 1
| > -
| | > None
| | > 4
> 5
>>> a = MOFraction(1, 2)
>>> b = MOFraction(1, 4)
>>> print(mofraction_mofraction(a, b))
+
> /
| > *
| | > 1
| | > 2
| > *
| | > 2
| | > 2
> /
| > 1
| > 4
>>> a = MOFraction(1, 2)
>>> b = MOFraction(1, 5)
>>> print(mofraction_mofraction(a, b))
+
> /
| > *
| | > 1
| | > 5
| > *
| | > 2
| | > 5
> /
| > *
| | > 1
| | > 2
| > *
| | > 5
| | > 2
"""
if not isinstance(left, MOFraction) or not isinstance(right, MOFraction):
raise AddError(f"Wrong type for left (got {left.__class__.__name__})"
f"or right (got {right.__class__.__name__})")
if left.denominator == right.denominator:
num = Tree("+", left.numerator, right.numerator)
return Tree("/", num, left.denominator)
denom_lcm = lcm(left.denominator, right.denominator)
if left.denominator == denom_lcm:
left_frac = left
else:
multiply_by = denom_lcm // left.denominator
left_num = Tree("*", left.numerator, MO.factory(multiply_by))
left_denom = Tree("*", left.denominator, MO.factory(multiply_by))
left_frac = Tree("/", left_num, left_denom)
if right.denominator == denom_lcm:
right_frac = right
else:
multiply_by = denom_lcm // right.denominator
right_num = Tree("*", right.numerator, MO.factory(multiply_by))
right_denom = Tree("*", right.denominator, MO.factory(multiply_by))
right_frac = Tree("/", right_num, right_denom)
return Tree("+", left_frac, right_frac)
# TODO: Faire un décorateur pour un enregistrement automatique |dim. mars 11 18:24:32 EAT 2018 # TODO: Faire un décorateur pour un enregistrement automatique |dim. mars 11 18:24:32 EAT 2018
ADDFUNCTIONS = { ADDFUNCTIONS = {
(MOnumber, MOnumber): monumber_monumber, (MOnumber, MOnumber): monumber_monumber,
(MOnumber, MOFraction): monumber_mofraction, (MOnumber, MOFraction): monumber_mofraction,
(MOFraction, MOnumber): mofraction_monumber, (MOFraction, MOnumber): mofraction_monumber,
(MOFraction, MOFraction): mofraction_mofraction,
} }
# ----------------------------- # -----------------------------

View File

@ -0,0 +1,77 @@
#!/usr/bin/env python
# encoding: utf-8
__all__ = ['gcd']
def gcd(a, b):
"""Compute gcd(a,b)
:param a: first number (need to support abs, comparison, * and %)
:param b: second number (need to support abs, comparison, * and %)
:returns: the gcd
>>> gcd(3, 15)
3
>>> gcd(15, 3)
3
>>> gcd(-3, -15)
-3
>>> gcd(5, 12)
1
>>> gcd(4, 14)
2
"""
pos_a, _a = (a >= 0), abs(a)
pos_b, _b = (b >= 0), abs(b)
gcd_sgn = (-1 + 2 * (pos_a or pos_b))
if _a > _b:
c = _a % _b
else:
c = _b % _a
if c == 0:
return gcd_sgn * min(_a, _b)
elif _a == 1:
return gcd_sgn * _b
elif _b == 1:
return gcd_sgn * _a
else:
return gcd_sgn * gcd(min(_a, _b), c)
def lcm(a, b):
"""Compute lcm(a,b)
:param a: first number (need to support abs, comparison, *, % and //)
:param b: second number (need to support abs, comparison, *, % and //)
:returns: the lcm
>>> lcm(3, 15)
15
>>> lcm(15, 3)
15
>>> lcm(-3, -15)
-15
>>> lcm(5, 12)
60
>>> lcm(4, 14)
28
"""
return (a * b) // gcd(a, b)
if __name__ == '__main__':
print(gcd(3, 15))
print(gcd(3, 15))
print(gcd(-15, -3))
print(gcd(-3, -12))
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

View File

@ -74,25 +74,21 @@ def monumber_mofraction(left, right):
> 5 > 5
>>> b = MOFraction(6, 5, True) >>> b = MOFraction(6, 5, True)
>>> print(monumber_mofraction(a, b)) >>> print(monumber_mofraction(a, b))
- /
> None > *
> / | > 4
| > * | > -
| | > 4 | | > None
| | > 6 | | > 6
| > 5 > 5
""" """
if not isinstance(left, MOnumber) or not isinstance(right, MOFraction): if not isinstance(left, MOnumber) or not isinstance(right, MOFraction):
raise MultiplyError(f"Wrong type for left (got {left.__class__.__name__}) \ raise MultiplyError(f"Wrong type for left (got {left.__class__.__name__}) \
or right (got {right.__class__.__name__})") or right (got {right.__class__.__name__})")
num = Tree("*", left, right._numerator) num = Tree("*", left, right.numerator)
frac = Tree("/", num, right._denominator) return Tree("/", num, right._denominator)
if right.negative:
return Tree("-", None, frac)
return frac
def mofraction_monumber(left, right): def mofraction_monumber(left, right):
""" Adding a monumber and a mofraction """ Adding a monumber and a mofraction
@ -115,12 +111,8 @@ def mofraction_monumber(left, right):
raise MultiplyError(f"Wrong type for left (got {left.__class__.__name__})" raise MultiplyError(f"Wrong type for left (got {left.__class__.__name__})"
f"or right (got {right.__class__.__name__})") f"or right (got {right.__class__.__name__})")
num = Tree("*", left._numerator, right) num = Tree("*", left.numerator, right)
frac = Tree("/", num, left._denominator) return Tree("/", num, left._denominator)
if left.negative:
return Tree("-", None, frac)
return frac
# TODO: Faire un décorateur pour un enregistrement automatique |dim. mars 11 18:24:32 EAT 2018 # TODO: Faire un décorateur pour un enregistrement automatique |dim. mars 11 18:24:32 EAT 2018
MULFUNCTIONS = { MULFUNCTIONS = {