Balancing chemical equations with Python – ChemPy package

In the evolving world of scientific computing, Python has emerged as a language of choice for researchers and analysts. One of the shining examples of Python’s application in the realm of chemistry is the ‘ChemPy’ package. This versatile library offers a wide array of functionalities catering to various aspects of chemistry, making it an invaluable tool for chemists, educators, and students alike.

In this article, we will explore the balancing of chemical equations using the ChemPy package.

What is ChemPy?

ChemPy is a Python package specifically designed for solving problems in chemistry. It provides a comprehensive suite of tools and functions that facilitate the simulation, analysis, and computation of chemical systems. From basic tasks like calculating chemical formulas to more complex processes like kinetic modeling, ChemPy stands as a robust and user-friendly framework.

Features of ChemPy

  • Chemical Arithmetic: ChemPy excels in handling basic chemical calculations, such as determining molecular weights, empirical formulas, and stoichiometric coefficients.
  • Kinetic Modeling: One of the standout features of ChemPy is its ability to model chemical kinetics. It supports the simulation of chemical reactions, allowing users to study reaction dynamics and mechanisms.
  • Equilibrium Calculations: The package can compute the equilibrium constant of a reaction at a given temperature, aiding in thermodynamic studies.
  • Support for Various Chemical Standards: ChemPy works seamlessly with standard chemical notation and data formats, ensuring compatibility and ease of integration with other tools and databases.

Installing ChemPy

ChemPy is available on the Python Package Index (PyPI) and can be installed using the pip command:

pip install chempy

Alternatively, you can install the package from the conda-forge channel using the conda command:

conda install -c conda-forge chempy

Working with chemical substances in ChemPy

ChemPy has a dedicated module for handling chemical substances, called chempy.Substance. This class represents a chemical substance and contains information about its composition, such as the chemical formula and molecular weight. Let’s see how we can create a Substance object in ChemPy:

from chempy import Substance
water = Substance.from_formula('H2O')
water
H2O

We can inspect the composition of a Substance object using the composition attribute. It will return a dictionary containing the atomic number of each element present in the substance as the key and the number of atoms of that element as the value:

water.composition
{1: 2, 8: 1}

Other attributes of the Substance class include mass, which returns the molecular weight of the substance, and charge, which returns the net charge of the substance.

water.charge
0
water.mass
18.015

ChemPy also has the ability to work with units. The Substance class has a molar_mass method that could be used to calculate the molar mass of the substance showing the units:

water.molar_mass()
array(18.015) * g/mol

Under the hood, ChemPy uses the Quantities package to handle units. The molar_mass method returns a Quantity object, which contains the value and unit of the molar mass. We can access the value and unit of the Quantity object using the magnitude and units attributes, respectively:

type(water.molar_mass())
quantities.quantity.Quantity
water.molar_mass().magnitude
array(18.015)
water.molar_mass().units
array(1.) * g/mol

One thing that is really useful is that you can get the formula of the substance in various formats. You can have it in plain text, HTML, or LaTeX:

water.name
'H2O'
water.html_name
'H2O'
water.latex_name
'H_{2}O'

Balancing chemical equations in ChemPy

Every chemical reaction can be represented by a chemical equation. A chemical equation is a symbolic representation of a chemical reaction, consisting of chemical formulas of the reactants and products. For example, the following equation represents the combustion of acetylene:

2 C2H2 + 5 O2 → 4 CO2 + 2 H2O

In this equation, C2H2 and O2 are the reactants, and CO2 and H2O are the products. The numbers in front of the chemical formulas are called stoichiometric coefficients and represent the number of molecules of each substance involved in the reaction.

maçarico

Acetylene is the fuel of some blowtorches

For balancing, we will use the chempy.balance_stoichiometry function. This function takes two arguments: a set of reactants and a set of products.

from chempy import balance_stoichiometry
r01 = balance_stoichiometry({"C2H2", "O2"}, {"CO2", "H2O"})
r01
(OrderedDict([('C2H2', 2), ('O2', 5)]), OrderedDict([('CO2', 4), ('H2O', 2)]))

As can be seen, the function returns a tuple of two ordered dictionaries. The first dictionary contains the stoichiometric coefficients of the reactants, and the second dictionary contains the stoichiometric coefficients of the products.

We can unpack this tuple:

r01_reac, r01_prod = r01
r01_reac
OrderedDict([('C2H2', 2), ('O2', 5)])
r01_prod
OrderedDict([('CO2', 4), ('H2O', 2)])

It would be useful to have the balanced equation in a more readable format. We can build a reaction with the Reaction class. It can be initialized with the reactants and products as obtained before:

from chempy import Reaction
r01_bal = Reaction(r01_reac, r01_prod)
r01_bal
2 C2H2 + 5 O2 → 4 CO2 + 2 H2O

The same could be achieved unpacking the tuple returned by balance_stoichiometry directly in the Reaction constructor:

Reaction(*r01)
2 C2H2 + 5 O2 → 4 CO2 + 2 H2O

The Reaction object has some useful methods. For example, we can get the chemical equation in various formats: plain text, HTML, and LaTeX.

For plain text, we can use the string method:

r01_bal.string()
'2 C2H2 + 5 O2 -> 4 CO2 + 2 H2O'

For HTML and LaTeX, we need, first, to create a dictionary mapping each substance string to the corresponding Substance object. Then, we can use the html and latex methods. The keys method of the Reaction object returns a set of the reactants and products:

r01_bal.keys()
{'C2H2', 'CO2', 'H2O', 'O2'}

With these, we can create the dictionary mapping the substance string to the Substance object with a dictionary comprehension:

r01_substances = {key: Substance.from_formula(key) for key in r01_bal.keys()}
r01_substances
{'C2H2': ,
 'O2': ,
 'H2O': ,
 'CO2': }

Now, we can use the html and latex methods passing the dictionary as an argument:

r01_bal.latex(r01_substances)
'2 C_{2}H_{2} + 5 O_{2} \\rightarrow 4 CO_{2} + 2 H_{2}O'
r01_bal.html(r01_substances)
'2 C2H2 + 5 O2 → 4 CO2 + 2 H2O'

Balancing redox equilibria in ChemPy

When balancing redox reactions, we need to take into account the transfer of electrons between the reactants and products. It is common to use the half-reaction method to balance redox reactions. In this method, the redox reaction is split into two half-reactions: the oxidation half-reaction and the reduction half-reaction. The oxidation half-reaction represents the loss of electrons, and the reduction half-reaction represents the gain of electrons. The two half-reactions are then balanced separately and combined to form the balanced redox reaction.

The half-reactions can be obtained from tabulated standard reduction potentials. The standard reduction potential of a redox reaction is the potential difference between the two half-reactions under standard conditions. The half-reaction with the more positive standard reduction potential is the reduction half-reaction, and the half-reaction with the more negative standard reduction potential is the oxidation half-reaction.

Here, we will consider the permanganate ion reduction by hydrogen peroxide in acidic solution:

permanganato peróxido

Potassium permanganate reaction with hydrogen peroxide

We can import the Equilibrium class from chempy. This class represents a chemical equilibrium and can be initialized with the reactants and products of the equilibrium. We are going to create two Equilibrium objects, one for the oxidation half-reaction and one for the reduction half-reaction:

from chempy import Equilibrium
r02_red = Equilibrium({'MnO4-': 1, 'H+': 8, 'e-': 5}, {'Mn+2': 1, 'H2O': 4})
r2_ox = Equilibrium({'H2O2': 1}, {'O2': 1, 'H+':2, 'e-':2})
r02_red
8 H+ + MnO4- + 5 e- ↔ 4 H2O + Mn+2
r2_ox
H2O2 ↔ 2 H+ + O2 + 2 e-

Following the procedure, we need to eliminate the electrons from the half-reactions. We can do this by adding the two half-reactions together. However, we need to make sure that the number of electrons in the oxidation half-reaction is equal to the number of electrons in the reduction half-reaction. We can do this by multiplying the oxidation half-reaction by the number of electrons in the reduction half-reaction and vice versa. This is what the eliminate function does. It takes two arguments: the first is an iterable object with both half-reactions, and the second is what should be eliminated. It returns a list of two coefficients, one for each half-reaction, that can be used to eliminate the electrons:

r02_e_coeffs = Equilibrium.eliminate((r02_red, r2_ox), 'e-')
r02_e_coeffs
[2, 5]

The final balanced equation can be obtained by adding the two half-reactions together, multiplied by the coefficients obtained from the eliminate function:

r02_bal = r02_red * r02_e_coeffs[0] + r2_ox * r02_e_coeffs[1]
r02_bal
6 H+ + 5 H2O2 + 2 MnO4- ↔ 8 H2O + 2 Mn+2 + 5 O2

For a LaTeX or HTML representation, we can use the latex and html methods, similarly to what we did before. So we need to create a dictionary mapping each substance string to the corresponding Substance object:

r02_substances = {key: Substance.from_formula(key) for key in r02_bal.keys()}
r02_substances
{'Mn+2': ,
 'MnO4-': ,
 'H2O': ,
 'H+': ,
 'H2O2': ,
 'O2': }

And then we can use the latex and html methods:

r02_bal.latex(r02_substances)
'6 H^{+} + 5 H_{2}O_{2} + 2 MnO_{4}^{-} \\rightleftharpoons 8 H_{2}O + 2 Mn^{2+} + 5 O_{2}'
r02_bal.html(r02_substances)
'6 H+ + 5 H2O2 + 2 MnO4- ↔ 8 H2O + 2 Mn2+ + 5 O2'

Conclusion

ChemPy embodies the intersection of chemistry and computational power, offering a platform that enhances the efficiency and scope of chemical analysis and research. Its integration into the Python ecosystem opens doors to a multitude of possibilities for innovation and discovery in the chemical sciences.

Whether you are a seasoned chemist, an aspiring student, or a professional in the field, ChemPy presents an opportunity to explore the depths of chemistry through a computational lens, making it a worthy addition to your scientific toolkit.

In this article, we have explored the balancing of chemical equations using the ChemPy package. We have seen how to create a Substance object and how to get the chemical formula in various formats. We have also seen how to balance chemical equations and redox reactions. The package has many more features, and we encourage you to explore them. Leave a comment below if you want us to cover other features of ChemPy in future articles.

References and Further Reading

For more information and to access the source code, visit the ChemPy GitHub page: ChemPy on GitHub.

More Python posts here on Chemistry Programming

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top