(expr, radical=False, clear=False, fraction=False, sign=True)
return do(expr)
Remove common factors from terms in all arguments without
    changing the underlying structure of the expr. No expansion or
    simplification (and no processing of non-commutatives) is performed.

    If radical=True then a radical common to all terms will be factored
    out of any Add sub-expressions of the expr.

    If clear=False (default) then coefficients will not be separated
    from a single Add if they can be distributed to leave one or more
    terms with integer coefficients.

    If fraction=True (default is False) then a common denominator will be
    constructed for the expression.

    If sign=True (default) then even if the only factor in common is a -1,
    it will be factored out of the expression.

    Examples
    ========

    >>> from sympy import factor_terms, Symbol
    >>> from sympy.abc import x, y
    >>> factor_terms(x + x*(2 + 4*y)**3)
    x*(8*(2*y + 1)**3 + 1)
    >>> A = Symbol('A', commutative=False)
    >>> factor_terms(x*A + x*A + x*y*A)
    x*(y*A + 2*A)

    When ``clear`` is False, a rational will only be factored out of an
    Add expression if all terms of the Add have coefficients that are
    fractions:

    >>> factor_terms(x/2 + 1, clear=False)
    x/2 + 1
    >>> factor_terms(x/2 + 1, clear=True)
    (x + 2)/2

    This only applies when there is a single Add that the coefficient
    multiplies:

    >>> factor_terms(x*y/2 + y, clear=True)
    y*(x + 2)/2
    >>> factor_terms(x*y/2 + y, clear=False) == _
    True

    If a -1 is all that can be factored out, to *not* factor it out, the
    flag ``sign`` must be False:

    >>> factor_terms(-x - y)
    -(x + y)
    >>> factor_terms(-x - y, sign=False)
    -x - y
    >>> factor_terms(-2*x - 2*y, sign=False)
    -2*(x + y)

    See Also
    ========
    gcd_terms, sympy.polys.polytools.terms_gcd
Remove common factors from terms in all arguments without
    changing the underlying structure of the expr. No expansion or
    simplification (and no processing of non-commutatives) is performed.
Remove common factors from terms in all arguments without changing the underlying structure of the expr . No expansion or simplification ( and no processing of non - commutatives ) is performed .
def factor_terms(expr, radical=False, clear=False, fraction=False, sign=True):
    """Remove common factors from terms in all arguments without
    changing the underlying structure of the expr. No expansion or
    simplification (and no processing of non-commutatives) is performed.

    If radical=True then a radical common to all terms will be factored
    out of any Add sub-expressions of the expr.

    If clear=False (default) then coefficients will not be separated
    from a single Add if they can be distributed to leave one or more
    terms with integer coefficients.

    If fraction=True (default is False) then a common denominator will be
    constructed for the expression.

    If sign=True (default) then even if the only factor in common is a -1,
    it will be factored out of the expression.

    Examples
    ========

    >>> from sympy import factor_terms, Symbol
    >>> from sympy.abc import x, y
    >>> factor_terms(x + x*(2 + 4*y)**3)
    x*(8*(2*y + 1)**3 + 1)
    >>> A = Symbol('A', commutative=False)
    >>> factor_terms(x*A + x*A + x*y*A)
    x*(y*A + 2*A)

    When ``clear`` is False, a rational will only be factored out of an
    Add expression if all terms of the Add have coefficients that are
    fractions:

    >>> factor_terms(x/2 + 1, clear=False)
    x/2 + 1
    >>> factor_terms(x/2 + 1, clear=True)
    (x + 2)/2

    This only applies when there is a single Add that the coefficient
    multiplies:

    >>> factor_terms(x*y/2 + y, clear=True)
    y*(x + 2)/2
    >>> factor_terms(x*y/2 + y, clear=False) == _
    True

    If a -1 is all that can be factored out, to *not* factor it out, the
    flag ``sign`` must be False:

    >>> factor_terms(-x - y)
    -(x + y)
    >>> factor_terms(-x - y, sign=False)
    -x - y
    >>> factor_terms(-2*x - 2*y, sign=False)
    -2*(x + y)

    See Also
    ========
    gcd_terms, sympy.polys.polytools.terms_gcd

    """
    from sympy.simplify.simplify import bottom_up

    def do(expr):
        is_iterable = iterable(expr)

        if not isinstance(expr, Basic) or expr.is_Atom:
            if is_iterable:
                return type(expr)([do(i) for i in expr])
            return expr

        if expr.is_Pow or expr.is_Function or \
                is_iterable or not hasattr(expr, 'args_cnc'):
            args = expr.args
            newargs = tuple([do(i) for i in args])
            if newargs == args:
                return expr
            return expr.func(*newargs)

        cont, p = expr.as_content_primitive(radical=radical)
        if p.is_Add:
            list_args = [do(a) for a in Add.make_args(p)]
            # get a common negative (if there) which gcd_terms does not remove
            if all(a.as_coeff_Mul()[0] < 0 for a in list_args):
                cont = -cont
                list_args = [-a for a in list_args]
            # watch out for exp(-(x+2)) which gcd_terms will change to exp(-x-2)
            special = {}
            for i, a in enumerate(list_args):
                b, e = a.as_base_exp()
                if e.is_Mul and e != Mul(*e.args):
                    list_args[i] = Dummy()
                    special[list_args[i]] = a
            # rebuild p not worrying about the order which gcd_terms will fix
            p = Add._from_args(list_args)
            p = gcd_terms(p,
                isprimitive=True,
                clear=clear,
                fraction=fraction).xreplace(special)
        elif p.args:
            p = p.func(
                *[do(a) for a in p.args])
        rv = _keep_coeff(cont, p, clear=clear, sign=sign)
        return rv
    expr = sympify(expr)
    return do(expr)
def factor_terms ( expr , radical = False , clear = False , fraction = False , sign = True ) : from sympy . simplify . simplify import bottom_up def do ( expr ) : is_iterable = iterable ( expr ) if not isinstance ( expr , Basic ) or expr . is_Atom : if is_iterable : return type ( expr ) ( [ do ( i ) for i in expr ] ) return expr if expr . is_Pow or expr . is_Function or is_iterable or not hasattr ( expr , 'args_cnc' ) : args = expr . args newargs = tuple ( [ do ( i ) for i in args ] ) if newargs == args : return expr return expr . func ( * newargs ) cont , p = expr . as_content_primitive ( radical = radical ) if p . is_Add : list_args = [ do ( a ) for a in Add . make_args ( p ) ] # get a common negative (if there) which gcd_terms does not remove if all ( a . as_coeff_Mul ( ) [ 0 ] < 0 for a in list_args ) : cont = - cont list_args = [ - a for a in list_args ] # watch out for exp(-(x+2)) which gcd_terms will change to exp(-x-2) special = { } for i , a in enumerate ( list_args ) : b , e = a . as_base_exp ( ) if e . is_Mul and e != Mul ( * e . args ) : list_args [ i ] = Dummy ( ) special [ list_args [ i ] ] = a # rebuild p not worrying about the order which gcd_terms will fix p = Add . _from_args ( list_args ) p = gcd_terms ( p , isprimitive = True , clear = clear , fraction = fraction ) . xreplace ( special ) elif p . args : p = p . func ( * [ do ( a ) for a in p . args ] ) rv = _keep_coeff ( cont , p , clear = clear , sign = sign ) return rv expr = sympify ( expr ) return do ( expr )