Calculate formula compositions for both sides of the specified reaction.

    If the compounds in the reaction all have formula, then calculate and
    return the chemical compositions for both sides, otherwise return `None`.

    Args:
        reaction: :class:`psamm.reaction.Reaction`.
        compound_formula: a map from compound id to formula.

def reaction_formula(reaction, compound_formula):
    """Calculate formula compositions for both sides of the specified reaction.

    If the compounds in the reaction all have formula, then calculate and
    return the chemical compositions for both sides, otherwise return `None`.

    Args:
        reaction: :class:`psamm.reaction.Reaction`.
        compound_formula: a map from compound id to formula.
    """

    def multiply_formula(compound_list):
        for compound, count in compound_list:
            yield count * compound_formula[compound.name]

    for compound, _ in reaction.compounds:
        if compound.name not in compound_formula:
            return None
    else:
        left_form = reduce(
            operator.or_, multiply_formula(reaction.left), Formula())
        right_form = reduce(
            operator.or_, multiply_formula(reaction.right), Formula())
    return left_form, right_form