From 3c133250ece0c8f4d572a66cee51f2ce8f872979 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Tue, 13 Mar 2018 17:12:41 +0300 Subject: [PATCH] Multiply and divide are ok for MOnumber and MOFraction --- mapytex/calculus/core/compute/divide.py | 158 ++++++++++++++++++++++ mapytex/calculus/core/compute/multiply.py | 30 +++- 2 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 mapytex/calculus/core/compute/divide.py diff --git a/mapytex/calculus/core/compute/divide.py b/mapytex/calculus/core/compute/divide.py new file mode 100644 index 0000000..1a5d38a --- /dev/null +++ b/mapytex/calculus/core/compute/divide.py @@ -0,0 +1,158 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017 lafrite +# +# Distributed under terms of the MIT license. + +""" +Divide MO +""" + +from ..tree import Tree +from ..MO.mo import MO, MOnumber +from ..MO.fraction import MOFraction +from .exceptions import DivideError + + +def divide(left, right): + """ Perform the addition of left and right + + :param left: left MO + :param right: right MO + :returns: Tree or MO + + >>> a = MOnumber(4) + >>> b = MOnumber(6) + >>> divide(a, b) + + >>> b = MOnumber(0) + >>> divide(a, b) + Traceback (most recent call last): + ... + mapytex.calculus.core.compute.exceptions.DivideError: Division by zero + + """ + try: + right.value + except AttributeError: + pass + else: + if right.value == 0: + raise DivideError("Division by zero") + + if right.value == 1: + return left + + return MULFUNCTIONS[(type(left), type(right))](left, right) + +def monumber_monumber(left, right): + """ Divide 2 monumbers + + :param left: left MOnumber + :param right: right MOnumber + :returns: MONumber + + >>> a = MOnumber(4) + >>> b = MOnumber(6) + >>> monumber_monumber(a, b) + + """ + return MOFraction(left, right) + +def monumber_mofraction(left, right): + """ Divide a monumber and a mofraction + + :param left: a monumber + :param right: a mofraction + :returns: Tree with the multiplication on the numerator + + >>> a = MOnumber(4) + >>> b = MOFraction(6, 5) + >>> print(monumber_mofraction(a, b)) + * + > 4 + > / + | > 5 + | > 6 + >>> b = MOFraction(6, 5, True) + >>> print(monumber_mofraction(a, b)) + * + > 4 + > - + | > None + | > / + | | > 5 + | | > 6 + """ + if not isinstance(left, MOnumber) or not isinstance(right, MOFraction): + raise DivideError(f"Wrong type for left (got {left.__class__.__name__}) \ + or right (got {right.__class__.__name__})") + + return Tree("*", left, right.inverse()) + +def mofraction_monumber(left, right): + """ Divide a monumber and a mofraction + + :param left: a mofraction + :param right: a monumber + :returns: Tree with a new calculus + + >>> a = MOFraction(6, 5) + >>> b = MOnumber(4) + >>> print(mofraction_monumber(a, b)) + * + > / + | > 6 + | > 5 + > / + | > 1 + | > 4 + """ + + if not isinstance(left, MOFraction) or not isinstance(right, MOnumber): + raise DivideError(f"Wrong type for left (got {left.__class__.__name__})" + f"or right (got {right.__class__.__name__})") + + right_fraction = MOFraction(1, right) + return Tree("*", left, right_fraction) + +def mofraction_mofraction(left, right): + """ Divide two mofractions + + :param left: a mofraction + :param right: a mofraction + :returns: Tree with a new calculus + + >>> a = MOFraction(1, 5) + >>> b = MOFraction(4, 5) + >>> print(mofraction_mofraction(a, b)) + * + > / + | > 1 + | > 5 + > / + | > 5 + | > 4 + + """ + + 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__})") + + return Tree("*", left, right.inverse()) + +# TODO: Faire un décorateur pour un enregistrement automatique |dim. mars 11 18:24:32 EAT 2018 +MULFUNCTIONS = { + (MOnumber, MOnumber): monumber_monumber, + (MOnumber, MOFraction): monumber_mofraction, + (MOFraction, MOnumber): mofraction_monumber, + (MOFraction, MOFraction): mofraction_mofraction, + } + +# ----------------------------- +# Reglages pour 'vim' +# vim:set autoindent expandtab tabstop=4 shiftwidth=4: +# cursor: 16 del diff --git a/mapytex/calculus/core/compute/multiply.py b/mapytex/calculus/core/compute/multiply.py index 621f4ad..37c2316 100644 --- a/mapytex/calculus/core/compute/multiply.py +++ b/mapytex/calculus/core/compute/multiply.py @@ -90,7 +90,7 @@ def monumber_mofraction(left, right): return Tree("/", num, right._denominator) def mofraction_monumber(left, right): - """ Adding a monumber and a mofraction + """ Multiply a monumber and a mofraction :param left: a mofraction :param right: a monumber @@ -113,11 +113,39 @@ def mofraction_monumber(left, right): num = Tree("*", left.numerator, right) return Tree("/", num, left._denominator) +def mofraction_mofraction(left, right): + """ Multiply two mofractions + + :param left: a mofraction + :param right: a mofraction + :returns: Tree with a new calculus + + >>> a = MOFraction(1, 5) + >>> b = MOFraction(4, 5) + >>> print(mofraction_mofraction(a, b)) + / + > * + | > 1 + | > 4 + > * + | > 5 + | > 5 + """ + + 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__})") + + num = Tree("*", left.numerator, right.numerator) + denom = Tree("*", left.denominator, right.denominator) + return Tree("/", num, denom) + # TODO: Faire un décorateur pour un enregistrement automatique |dim. mars 11 18:24:32 EAT 2018 MULFUNCTIONS = { (MOnumber, MOnumber): monumber_monumber, (MOnumber, MOFraction): monumber_mofraction, (MOFraction, MOnumber): mofraction_monumber, + (MOFraction, MOFraction): mofraction_mofraction, } # -----------------------------