#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2017 lafrite # # Distributed under terms of the MIT license. """ Multiply MO """ from ..tree import Tree from ..MO.mo import MO, MOnumber, MOstr from ..MO.fraction import MOFraction from ..MO.monomial import MOMonomial from .exceptions import MultiplyError from .type_filter import args_are def multiply(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) >>> multiply(a, b) >>> b = MOnumber(0) >>> multiply(a, b) """ if left.value == 0 or right.value == 0: return MOnumber(0) elif left.value == 1: return right elif right.value == 1: return left return MULFUNCTIONS[(type(left), type(right))](left, right) @args_are(MOnumber, MOnumber) def monumber_monumber(left, right): """ Multiply 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) @args_are(MOnumber, MOFraction) def monumber_mofraction(left, right): """ Multiply 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 | > 6 > 5 >>> b = MOFraction(6, 5, True) >>> print(monumber_mofraction(a, b)) / > * | > 4 | > - | | > None | | > 6 > 5 """ if not isinstance(left, MOnumber) or not isinstance(right, MOFraction): raise MultiplyError(f"Wrong type for left (got {left.__class__.__name__}) \ or right (got {right.__class__.__name__})") num = Tree("*", left, right.numerator) return Tree("/", num, right._denominator) @args_are(MOFraction, MOnumber) def mofraction_monumber(left, right): """ Multiply 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 | > 4 > 5 """ if not isinstance(left, MOFraction) or not isinstance(right, MOnumber): raise MultiplyError(f"Wrong type for left (got {left.__class__.__name__})" f"or right (got {right.__class__.__name__})") num = Tree("*", left.numerator, right) return Tree("/", num, left._denominator) @args_are(MOFraction, MOFraction) 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) @args_are((MOnumber, MOFraction), MOstr) def moscalar_mostr(left, right): """ Multiply a scalar with a letter >>> a = MOnumber(2) >>> b = MOstr('x') >>> moscalar_mostr(a, b) >>> a = MOFraction(1, 5) >>> moscalar_mostr(a, b) """ return MOMonomial(left, right) @args_are(MOstr, (MOnumber, MOFraction)) def mostr_moscalar(left, right): """ Multiply a scalar with a letter >>> a = MOstr('x') >>> b = MOnumber(2) >>> mostr_moscalar(a, b) >>> b = MOFraction(1, 5) >>> mostr_moscalar(a, b) """ return MOMonomial(right, left) @args_are((MOnumber, MOFraction), MOMonomial) def moscalar_monomonial(left, right): """ Multiply a scalar with a monomial >>> a = MOnumber(4) >>> b = MOMonomial(5, 'x', 3) # >>> print(moscalar_monomonial(a, b)) """ coefficient = Tree('*', left, right._coefficient) return Tree('*', coefficient, MOMonomial(1, right._variable, right._power)) # 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