# ChemPy – python package

## Chapter 178: ChemPy – python package

ChemPy is a python package designed mainly to solve and address problems in physical, analytical and inorganic Chemistry. It is a free, open-source Python toolkit for chemistry, chemical engineering, and materials science applications.

## Section 178.1: Parsing formulae

`from chempy import Substanceferricyanide = Substance.from_formula('Fe(CN)6-3') ferricyanide.composition == {0: -3, 26: 1, 6: 6, 7: 6} Trueprint(ferricyanide.unicode_name)Fe(CN)₆³⁻print(ferricyanide.latex_name + ", " + ferricyanide.html_name)Fe(CN)_{6}^{3-}, Fe(CN)63-print('%.3f' % ferricyanide.mass)211.955`

In composition, the atomic numbers (and 0 for charge) is used as keys and the count of each kind became respective value.

## Section 178.2: Balancing stoichiometry of a chemical reaction

`from chempy import balance_stoichiometry # Main reaction in NASA's booster rockets:reac, prod = balance_stoichiometry({'NH4ClO4', 'Al'}, {'Al2O3', 'HCl', 'H2O', 'N2'})from pprint import pprintpprint(reac){'Al': 10, 'NH4ClO4': 6}pprint(prod){'Al2O3': 5, 'H2O': 9, 'HCl': 6, 'N2': 3}from chempy import mass_fractionsfor fractions in map(mass_fractions, [reac, prod]):… pprint({k: '{0:.3g} wt%'.format(v*100) for k, v in fractions.items()})…{'Al': '27.7 wt%', 'NH4ClO4': '72.3 wt%'}{'Al2O3': '52.3 wt%', 'H2O': '16.6 wt%', 'HCl': '22.4 wt%', 'N2': '8.62 wt%'}`

## Section 178.3: Balancing reactions

`from chempy import Equilibriumfrom sympy import symbolsK1, K2, Kw = symbols('K1 K2 Kw')e1 = Equilibrium({'MnO4-': 1, 'H+': 8, 'e-': 5}, {'Mn+2': 1, 'H2O': 4}, K1)e2 = Equilibrium({'O2': 1, 'H2O': 2, 'e-': 4}, {'OH-': 4}, K2)coeff = Equilibrium.eliminate([e1, e2], 'e-')coeff[4, -5]redox = e1coeff[0] + e2coeff[1]print(redox)20 OH- + 32 H+ + 4 MnO4- = 26 H2O + 4 Mn+2 + 5 O2; K14/K25 autoprot = Equilibrium({'H2O': 1}, {'H+': 1, 'OH-': 1}, Kw) n = redox.cancel(autoprot)n20redox2 = redox + n*autoprotprint(redox2)`

GoalKicker.com – Python® Notes for Professionals 693

`12 H+ + 4 MnO4- = 4 Mn+2 + 5 O2 + 6 H2O; K14Kw20/K2*5`

## Section 178.4: Chemical equilibria

`from chempy import Equilibriumfrom chempy.chemistry import Specieswater_autop = Equilibrium({'H2O'}, {'H+', 'OH-'}, 10-14) # unit "molar" assumed ammonia_prot = Equilibrium({'NH4+'}, {'NH3', 'H+'}, 10-9.24) # same here from chempy.equilibria import EqSystemsubstances = map(Species.from_formula, 'H2O OH- H+ NH3 NH4+'.split())eqsys = EqSystem([water_autop, ammonia_prot], substances)print('\n'.join(map(str, eqsys.rxns))) # "rxns" short for "reactions"H2O = H+ + OH-; 1e-14NH4+ = H+ + NH3; 5.75e-10from collections import defaultdictinit_conc = defaultdict(float, {'H2O': 1, 'NH3': 0.1})x, sol, sane = eqsys.root(init_conc)assert sol['success'] and saneprint(sorted(sol.keys())) # see package "pyneqsys" for more info['fun', 'intermediate_info', 'internal_x_vecs', 'nfev', 'njev', 'success', 'x', 'x_vecs'] print(', '.join('%.2g' % v for v in x))1, 0.0013, 7.6e-12, 0.099, 0.0013`

## Section 178.5: Ionic strength

`from chempy.electrolytes import ionic_strengthionic_strength({'Fe+3': 0.050, 'ClO4-': 0.150}) == .3True`

## Section 178.6: Chemical kinetics (system of ordinary di erential equations)

`from chempy import ReactionSystem # The rate constants below are arbitrary rsys = ReactionSystem.from_string("""2 Fe+2 + H2O2 -> 2 Fe+3 + 2 OH-; 422 Fe+3 + H2O2 -> 2 Fe+2 + O2 + 2 H+; 17H+ + OH- -> H2O; 1e10H2O -> H+ + OH-; 1e-4Fe+3 + 2 H2O -> FeOOH(s) + 3 H+; 1FeOOH(s) + 3 H+ -> Fe+3 + 2 H2O; 2.5""") # "[H2O]" = 1.0 (actually 55.4 at RT) from chempy.kinetics.ode import get_odesys odesys, extra = get_odesys(rsys)from collections import defaultdictimport numpy as nptout = sorted(np.concatenate((np.linspace(0, 23), np.logspace(-8, 1))))c0 = defaultdict(float, {'Fe+2': 0.05, 'H2O2': 0.1, 'H2O': 1.0, 'H+': 1e-7, 'OH-': 1e-7})result = odesys.integrate(tout, c0, atol=1e-12, rtol=1e-14)import matplotlib.pyplot as plt= plt.subplot(1, 2, 1)= result.plot(names=[k for k in rsys.substances if k != 'H2O'])= plt.legend(loc='best', prop={'size': 9}); _ = plt.xlabel('Time'); _ = plt.ylabel('Concentration')= plt.subplot(1, 2, 2)= result.plot(names=[k for k in rsys.substances if k != 'H2O'], xscale='log', yscale='log')= plt.legend(loc='best', prop={'size': 9}); _ = plt.xlabel('Time'); _ = plt.ylabel('Concentration')= plt.tight_layout() plt.show()`

GoalKicker.com – Python® Notes for Professionals 694