#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2017 lafrite # # Distributed under terms of the MIT license. """ Adding MO """ from ..tree import Tree from ..operator import OPERATORS from ..MO.mo import MO, MOnumber, MOstr from ..MO.fraction import MOFraction from .exceptions import AddError from .arithmetic import lcm def add(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) >>> add(a, b) >>> b = MOnumber(0) >>> add(a, b) """ if left.value == 0: return right elif right.value == 0: return left return ADDFUNCTIONS[(type(left), type(right))](left, right) def monumber_monumber(left, right): """ Adding 2 monumbers :param left: left MOnumber :param right: right MOnumber :returns: MONumber >>> a = MOnumber(4) >>> b = MOnumber(6) >>> monumber_monumber(a, b) """ return MO.factory(left.value + right.value) def monumber_mofraction(left, right): """ Adding a monumber and a mofraction :param left: a monumber :param right: a mofraction :returns: Tree with the number converted into a mofraction >>> a = MOnumber(4) >>> b = MOFraction(6, 5) >>> print(monumber_mofraction(a, b)) + > / | > 4 | > 1 > / | > 6 | > 5 """ if not isinstance(left, MOnumber) or not isinstance(right, MOFraction): raise AddError(f"Wrong type for left (got {left.__class__.__name__}) \ or right (got {right.__class__.__name__})") left_fraction = MOFraction(left, MOnumber(1)) return Tree("+", left_fraction, right) def mofraction_monumber(left, right): """ Adding a monumber and a mofraction :param left: a mofraction :param right: a monumber :returns: Tree with the number converted into a mofraction >>> a = MOFraction(6, 5) >>> b = MOnumber(4) >>> print(mofraction_monumber(a, b)) + > / | > 6 | > 5 > / | > 4 | > 1 """ if not isinstance(left, MOFraction) or not isinstance(right, MOnumber): raise AddError(f"Wrong type for left (got {left.__class__.__name__})" f"or right (got {right.__class__.__name__})") right_fraction = MOFraction(right, MOnumber(1)) 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 ADDFUNCTIONS = { (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